Educational Codeforces Round 84 D permutation
题意:给定permutation,问p^K,使存在环对应的color相等。求min k。
思路:环点数为m,若k为m的因数,则可拆成小环。所以对于每个换枚举因数即可。
#include<cstdio> #include<algorithm> #include<iostream> #include<map> #include<string> #include<vector> #include<set> #include<cmath> #define ll long long using namespace std; const int maxn=2e5+5; int c[maxn]; int p[maxn]; int vis[maxn]; vector<int> vec; int ans; bool can(int sta, int k){//vec中是排好序的,所以可以这样写 for(int i=sta+k;i<vec.size();i+=k){ if(c[vec[i]]!=c[vec[i-k]])return false; } return true; } int findans(){ int m=vec.size(); int sm=(int)sqrt((double)m); for(int k=1;k<=sm;k++){ if(m%k!=0)continue; for(int sta=0;sta<k;sta++){ if(can(sta, k)){ ans=min(ans, k); break; } } if(k!=m/k){ for(int sta=0;sta<m/k;sta++){ if(can(sta, m/k)){ ans=min(ans, m/k); break; } } } } } void dfs(int i){//找环 if(vis[i])return; vis[i]=1; vec.push_back(i); dfs(p[i]); } void solve(){ 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]=0; ans=0x3f3f3f3f; for(int i=1;i<=n;i++){ if(vis[i])continue; else{ vec.clear(); dfs(i); // cout<<vec.size()<<"\n"; findans(); } } printf("%d\n", ans); } int main(){ freopen("in.txt","r",stdin); int t;scanf("%d",&t); while(t--){ solve(); } }

浙公网安备 33010602011771号