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();
    }
}

 

posted @ 2020-03-25 09:19  aaaaaaaaaaaaaa123  阅读(144)  评论(0)    收藏  举报