很水的一道题
这题考虑并查集,画个示意图
比如第三个样例:
6
4 6 2 1 5 3
图解:
https://www.luogu.com.cn/paste/sm12q91d
易证:把每一个 $i$ 和 $a_i$ 连一条边,那么整个图一定被分为多个连通块
这样就用一个带计数的并查集就可以轻松解决啦qwq
代码如下:
#include<iostream>
using namespace std;
int n;
int a[200010],f[200010],cnt[200010];
int zbb(int x){return f[x]=x==f[x]?x:zbb(f[x]);}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)f[i]=i,cnt[i]=1;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
int xx=zbb(a[i]),x=zbb(i);
if(x!=xx)
{
f[x]=xx;
cnt[xx]+=cnt[x];
}
}
for(int i=1;i<=n;i++)
{
int x=zbb(i);
printf("%d ",cnt[x]);
}
printf("\n");
}
}