Codeforces1327D. Infinite Path (图论/思维)

Description

You are given a colored permutation p1,p2,…,pn. The i-th element of the permutation has color ci.

Let’s define an infinite path as infinite sequence i,p[i],p[p[i]],p[p[p[i]]]… where all elements have same color (c[i]=c[p[i]]=c[p[p[i]]]=…).

We can also define a multiplication of permutations a and b as permutation c=a×b where c[i]=b[a[i]]. Moreover, we can define a power k of permutation p as pk=p×p×⋯×pk times.

Find the minimum k>0 such that pk has at least one infinite path (i.e. there is a position i in pk such that the sequence starting from i is an infinite path).

It can be proved that the answer always exists.

Input

The first line contains single integer T (1≤T≤104) — the number of test cases.

Next 3T lines contain test cases — one per three lines. The first line contains single integer n (1≤n≤2⋅105) — the size of the permutation.

The second line contains n integers p1,p2,…,pn (1≤pi≤n, pi≠pj for i≠j) — the permutation p.

The third line contains n integers c1,c2,…,cn (1≤ci≤n) — the colors of elements of the permutation.

It is guaranteed that the total sum of n doesn’t exceed 2⋅105.

Output

Print T integers — one per test case. For each test case print minimum k>0 such that pk has at least one infinite path.

扫描二维码关注公众号,回复: 11272033 查看本文章
Note

In the first test case, p1=p=[1,3,4,2] and the sequence starting from 1: 1,p[1]=1,… is an infinite path.

In the second test case, p5=[1,2,3,4,5] and it obviously contains several infinite paths.

In the third test case, p2=[3,6,1,8,7,2,5,4] and the sequence starting from 4: 4,p2[4]=8,p2[8]=4,… is an infinite path since c4=c8=4.

题目大意

给出一个数组p,p[i]表示该点的下一个元素的下标(p数组是一个排列)
给出一个数组c,c[i]表示第i个元素的颜色
求经过最少置换后的元素有一条无限路径的元素颜色一样
(每次置换p[i]=p[p[i]])

思路

无限路径也就是环。
首先因为p是一个排列,那构成的路径肯定是一个或多个简单环。因为每一个点只在p数组中出现一次,那意味着只有一个入度。而且每一个点都有出度,所以构成的都是简单环。
对于每一个环每一次置换路径都指向下一个节点
以6个节点为例:(左:p1 ,右:p2)

p3

那p4呢?

可以发现其实p4和p2是一样的gcd(4,6)=2
所以我们可以找出所有的环,对k进行枚举,再枚举起点,判断是否颜色相等
对于一个数的因子,可以先预处理出来

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
int p[maxn],c[maxn],vis[maxn];
vector<int> loop;
vector<int> factor[maxn];
int cal(){
    int l=loop.size(),ans=inf;
    for(int k=0;k<factor[l].size();++k){
        int len=factor[l][k];
        for(int i=0;i<len;++i){
            int ju=1;
            for(int j=i;j<l;j+=len){
                if(c[loop[j]]!=c[loop[i]]){
                    ju=0;
                    break;
                }
            }
            if(ju){
                ans=min(ans,len);
                break;
            }
        }
    }
    return ans;
}
int main()
{
    for(int i=1;i<maxn;++i){
        for(int j=i;j<maxn;j+=i){
            factor[j].push_back(i);
        }
    }
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;++i)scanf("%d",&p[i]);
        for(int i=1;i<=n;++i)scanf("%d",&c[i]);
        int ans=inf;
        for(int i=1;i<=n;++i){
            if(vis[i]==0){
                loop.clear();
                int now=i;
                while(vis[now]==0){
                    vis[now]=1;
                    loop.push_back(now);
                    now=p[now];
                }
                ans=min(ans,cal());
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43984169/article/details/105679412