日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CodeForces - 1327D Infinite Path(图论综合)

發布時間:2024/4/11 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 1327D Infinite Path(图论综合) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:首先給出一個 1 ~ n 的排列,用 p 數組表示,再給出給個點的顏色,用 c 數組表示

然后拋出Infinite Path的定義:對于某個 i ,p[ i ] , p[ p[ i ] ] , p[ p[ p[ i ] ] ] 無限嵌套下去,且每個位置的顏色相同,即 c[ i ] = c[ p[ i ] ] = c[ p[ p[ i ] ] ] = c[ p[ p[ p[ i ] ] ] ] 等等等等

下面重載一下排列的乘法運算,假如 a 和 b 是 1 ~ n 的兩個排列,那么 a * b = b[ a[ i ] ] ,a * a = a[ a [ i ] ]?

從而重載一下排列的乘方運算,p^k = p * p * p ... * p ( k 個 p )

題目要求我們找到一個最小的 k ,使得給出的排列 p 的 k 次方,存在一個 i ,可以滿足上述的Infinite Path

題目分析:讀完題后,不難想到如果想要找到Infinite Path的話,必然是一個循環,而 1 ~ n 的一個排列,如果轉換為有向圖的形式,可以視為數個不相交的有向環,之前做題記住的結論,忘記是怎么證明的了,這樣就可以將給出的排列 p 以有向圖的形式表示,接下來結合前幾周離散數學新學到的知識(學以致用)

?可以將 p^k 這個抽象的概念具體化,簡單來說,p^k 就是在 p 這個有向圖中,經過長度為 k 的步長可以到達的關系

再換句話說,p^k 就是在環中將距離相隔為 k 的數個點按照原次序重新組合成一個新的環

如果上面這句話不好理解的話,對于題目給出的第三個樣例畫一下圖就好理解了

綜上所述,現在題目就轉換為了,在數列 p 的所有環中,能否找到一個等差 k ,使得環上所有滿足等差關系的位置:pos , pos + k , pos + 2 * k , pos + 3 * k 等等位置的顏色相同,維護這個最小的 k 就是答案了

到此為止這個題目剩下的就是實現了,比賽的時候明明已經到了這一步,卻卡在了如何在環上找到等差的位置這里,不會實現,還是自己太菜了啊,賽后看了大佬的代碼發現只需要nlogn維護因子就好了,因為如果想滿足在環上滿足等差,那么這個差值 k 一定是環的長度的因子,對于每個長度的因子,nlogn預處理一下就可以了

代碼:
?

#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e5+100;int p[N],c[N];bool vis[N];vector<int>d[N];int cal(vector<int>loop) {int mmin=inf;for(auto len:d[loop.size()])//枚舉每個因子作為差值 k {for(int i=0;i<len;i++)//枚舉起點 {bool flag=true;for(int j=i;j<loop.size();j+=len){if(c[loop[i]]!=c[loop[j]]){flag=false;break;}}if(flag)mmin=min(mmin,len);}}return mmin; }int main() { #ifndef ONLINE_JUDGE // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); #endif // ios::sync_with_stdio(false);for(int i=1;i<N;i++)//預處理因子for(int j=i;j<N;j+=i)d[j].push_back(i);int w;cin>>w;while(w--){int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",p+i);for(int i=1;i<=n;i++)scanf("%d",c+i);for(int i=1;i<=n;i++)vis[i]=false;int ans=n;for(int i=1;i<=n;i++){if(vis[i])continue;int k=i;vector<int>loop;//找環while(!vis[k]){loop.push_back(k);vis[k]=true;k=p[k];}ans=min(ans,cal(loop));}printf("%d\n",ans);}return 0; }

?

總結

以上是生活随笔為你收集整理的CodeForces - 1327D Infinite Path(图论综合)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。