2020牛客多校 第五场 E-Bogo Sort

题目

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/kosf_/article/details/107712084