Educational Codeforces Round 84 (Rated for Div. 2)D(枚举环长度因子)
找到所有环,以环长度的因子为步长进行跳跃,如果每次跳跃颜色都相同,说明经过步长次转换后的序列存在颜色相同的无穷路径。
1 #define HAVE_STRUCT_TIMESPEC 2 #include<bits/stdc++.h> 3 using namespace std; 4 int a[200007],b[200007]; 5 int vis[200007]; 6 int loop[200007]; 7 int res; 8 int main(){ 9 ios::sync_with_stdio(false); 10 cin.tie(NULL); 11 cout.tie(NULL); 12 int t; 13 cin>>t; 14 while(t--){ 15 res=1e9; 16 int n; 17 cin>>n; 18 for(int i=1;i<=n;++i) 19 cin>>a[i]; 20 for(int i=1;i<=n;++i) 21 cin>>b[i]; 22 for(int i=1;i<=n;++i) 23 vis[i]=0; 24 for(int i=1;i<=n;++i){ 25 if(vis[i]) 26 continue; 27 int ans=1; 28 int now=i; 29 int to=a[i]; 30 vis[i]=1; 31 vis[a[i]]=1; 32 loop[1]=b[now]; 33 loop[2]=b[to]; 34 while(to!=now){ 35 to=a[to]; 36 vis[to]=1; 37 ++ans; 38 loop[1+ans]=b[to]; 39 } 40 for(int j=1;j*j<=ans;++j){ 41 if(ans%j) 42 continue; 43 int flag=0; 44 for(int k=1;k<=j;++k){ 45 flag=0; 46 for(int l=k+j;l<=ans;l+=j){ 47 if(loop[l]!=loop[l-j]){ 48 flag=1; 49 } 50 } 51 if(!flag){ 52 res=min(res,j); 53 break; 54 } 55 } 56 for(int k=1;k<=ans/j;++k){ 57 flag=0; 58 for(int l=k+ans/j;l<=ans;l+=ans/j){ 59 if(loop[l]!=loop[l-ans/j]){ 60 flag=1; 61 } 62 } 63 if(!flag){ 64 res=min(res,ans/j); 65 break; 66 } 67 } 68 } 69 res=min(res,ans); 70 } 71 cout<<res<<"\n"; 72 } 73 return 0; 74 }
保持热爱 不懈努力
不试试看怎么知道会失败呢(划掉)
世上无难事 只要肯放弃(划掉)