题目
题目链接:https://ac.nowcoder.com/acm/contest/5670/E
思路
群论+大整数乘法
求循环节的lcm即可
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
int a[100010],cnt[100010],prime[100010],N=100000,primenum[100010];
bool vis[100100],vis2[1000010];
int num[100010];
int len=1;int n;
void cal(int x){
for(int i=1;i<=len;i++) num[i]*=x;
for(int i=1;i<len;i++) if(num[i]>9) num[i+1]+=num[i]/10,num[i]%=10;
while(len<n&&num[len]>9) num[len+1]=num[len]/10,num[len++]%=10;
}
signed main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int num1=0;
for(int i=2;i<=N;i++){
if(!vis[i]){
for(int j=i*2;j<=n;j+=i) vis[j]=1;
++num1;
prime[num1]=i;}
}
//cout<<2<<endl;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
num[1]=1LL;
int l=0;
// cout<<2<<endl;
for(int i=1;i<=n;i++){
int j=i;
if(!vis2[j]){
l++;
while(!vis2[j]){
vis2[j]=1,cnt[l]++;
j=a[j];
}
}
}
// cout<<l<<endl;
for(int i=1;i<=l;i++){
for(int j=1;j<=num1&&cnt[i]>1;j++){
int t=0;
// cout<<prime[j]<<endl;
while(cnt[i]%prime[j]==0){
cnt[i]/=prime[j];t++;
}
primenum[prime[j]]=max(t,primenum[prime[j]]);
//cout<<primenum[prime[j]]<<endl;
}
}
for(int i=1;i<=num1;i++) while(primenum[prime[i]]--){
//cout<<prime[i]<<endl;
cal(prime[i]);
}
for(int i=len;i>=1;i--) cout<<num[i];
cout<<endl;
return 0;
}