Sample Input
2 3 1 3 2 6 2 3 4 5 6 1
Sample Output
2 6
题意:给一个转置求它的循环长度
题解:分解成循环求最小公倍数
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define MOD 3221225473
#define N 100005
#define MIN 0
#define MAX 1000001
const int maxn = 3000005;
int a[maxn],vis[maxn],sum[maxn];
void fin(int num)
{
int tt;
for(int i = 2; i <= num; i++)
{
tt = 0;
while(num%i == 0)
{
num/=i;
tt++;
}
if(tt > sum[i])
sum[i] = tt;
}
}
ll pow_mod(ll q,int n,ull mod)
{
if(n == 0)
return 1;
ll x = pow_mod(q,n/2,mod);
ll ans = (ll)x*x%mod;
if(n %2 == 1)
ans = ans *q % mod;
return ans;
}
int main()
{
int n,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ll ans;
for(int i = 1; i <= n; i++)
scanf("%d",&a[i]);
memset(vis,0,sizeof(vis));
memset(sum,0,sizeof(sum));
for(int i = 1; i <= n; i++)
{
if(vis[i])
continue;
int tmp = i;
int num = 0;
while(!vis[tmp])
{
vis[tmp] = 1;
tmp = a[tmp];
num ++;
}
//printf("num:%d\n",num);
fin(num);
}
ans = 1;
for(int i = 2; i <= n; i++)
if(sum[i])
{
//printf("%d\n",sum[i]);
ans = (ans * pow_mod(i,sum[i],(ll)MOD))%MOD;
}
printf("%I64d\n",ans);
}
return 0;
}