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 ",num); fin(num); } ans = 1; for(int i = 2; i <= n; i++) if(sum[i]) { //printf("%d ",sum[i]); ans = (ans * pow_mod(i,sum[i],(ll)MOD))%MOD; } printf("%I64d ",ans); } return 0; }