https://ac.nowcoder.com/acm/contest/5670
Bogo sort
题解:https://blog.nowcoder.net/n/59a8480b4bbf4e69b1523bbaa07a0c7e
代码:来自https://ac.nowcoder.com/acm/contest/view-submission?submissionId=44402547
#include<bits/stdc++.h> using namespace std; const int maxn=1e5+5; int n,l,r,cnt=1,ans,len=1,a[maxn],c[maxn],d[maxn],e[maxn],f[maxn],g[maxn],an[maxn]={0,1}; bool b[maxn]; void mul(int x)//大数乘 { for(int i=1;i<=len;i++) an[i]*=x; for(int i=1;i<len;i++)if(an[i]>9) an[i+1]+=an[i]/10,an[i]%=10; while(len<n&&an[len]>9) an[len+1]+=an[len]/10,an[len++]%=10; an[len+1]=0; } int main() { for(int i=2;i<maxn;i++) { if(!d[i]) { for(int j=i*2;j<maxn;j+=i) d[j]=1; e[++ans]=i; } } //素数筛求出质数 存在e数组中 scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++)//求出每个置换群的点的个数,存在c数组中//求环的长度 { l=i,r=0; while(!b[l]) b[l]=1,r=1,c[cnt]++,l=a[l]; if(r) cnt++; } /*高精度 问题是高精度求lcm是个麻烦的事情,万幸的是,这些群的大小都是int型的,因此gcd是很好求的。 可是要用到大数除,诶这就有点麻烦了,对于一个根本忘了怎么写高精度的蒟蒻来说,除法是个难于上青天的事情。 但是蒟蒻脑子好使,可以用另一种方式来求lcm。考虑分解质因数,对于每个质数记录每个数的质因数的个数的最大值,有点绕呵,举个例子吧。 比如有2,3,42,3,42,3,4要求它们的最小公倍数,则我只要分解: 2=2,3=3,4=2*2 那么2有max(1,2)次,3有1次,因此它们的最小公倍数是2^2*3^1=12,没有问题。 它的原理是:任意一对数,它们如果有质因子相同,那么根据lcm=a*b/gcd可知,它会将公共的部分除掉,相当于对于每个质因子的个数求个max即可。 比如有质数pr,a=pr^3*……,b=pr^5*...,则它们的公共部分是pr^3,相乘之后有pr^8,除掉后有pr^5 也就是pr^{max(3,5)} */ for(int i=0;i<cnt;i++)//遍历质数 { for(int j=1,t=0;j<=ans&&c[i]>1;j++)//遍历每个c[i]含有这个质数 { while(c[i]%e[j]==0) t++,c[i]/=e[j]; f[e[j]]=max(f[e[j]],t); t=0; } } for(int i=1;i<=ans;i++) while(f[e[i]]--) mul(e[i]); //把每个质数乘起来 for(int i=len;i>=1;i--) printf("%d",an[i]);//反着输出 return 0; }