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×⋯×pk 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.
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;
}