1. 并查集
#include<iostream>
#include<cstdio>
using namespace std;
const int N=2e5+10;
int find(int x);
int T;
int n;
int p[N], cnt[N];
signed main()
{
cin>>T;
while(T--)
{
scanf("%d", &n);
for(int i=1;i<=n;i++) p[i]=i, cnt[i]=1;
for(int i=1;i<=n;i++)
{
int j;
scanf("%d", &j);
int a=find(i), b=find(j);
if(a!=b)
{
cnt[b]+=cnt[a];
p[a]=b;
}
}
for(int i=1;i<=n;i++) printf("%d ", cnt[find(i)]);
puts("");
}
}
int find(int x)
{
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
2. dfs
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=2e5+10;
int find(int x);
int dfs(int now, int num, int root);
int T;
int n;
int p[N];
int cnt[N];
signed main()
{
cin>>T;
while(T--)
{
memset(cnt, 0, sizeof cnt);
scanf("%d", &n);
for(int i=1;i<=n;i++) scanf("%d", &p[i]);
for(int i=1;i<=n;i++)
if(cnt[i]) printf("%d ", cnt[i]);
else printf("%d ", dfs(p[i], 1, i));
puts("");
}
}
int dfs(int now, int num, int root)
{
if(now==root)
{
cnt[root]=num;
return num;
}
cnt[now]=dfs(p[now], num+1, root);
return cnt[now];
}