2020牛客多校第五场E题Bogo Sort(置换群求lcm高精度)
题目链接 https://ac.nowcoder.com/acm/contest/5670/E
题意:给你一个置换数组p,求有多少个序列可以求这个置换数组换为初始数组[1,2,3...n],答案对10^n取余。
题解:显然这是一个置换群问题,关于置换群,我们知道存在环,置换len次之后回到数组p,我们可以暴力求解每个环的长度,再求lcn(所有环的长度)就是本题的答案。
爆longlong,爆__int128 要么高精度模板要么就直接java大法。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import java.math.BigInteger; import java.util.Scanner; public class Main{ static int maxn=100005; static boolean vis[]=new boolean[maxn]; static int a[]=new int[maxn]; static int sum=0; static BigInteger mod=BigInteger.ONE; static BigInteger lcm(BigInteger x, BigInteger y){ return x.multiply(y).divide(x.gcd(y)); } public static void main(String[] args){ Scanner cin = new Scanner(System.in); int n; n=cin.nextInt(); for(int i=1;i<=n;i++) a[i]=cin.nextInt(); BigInteger ans=BigInteger.ONE; for(int i=1;i<=n;i++){ if(vis[i]) continue; sum=0; int nxt=i; while(!vis[nxt]){ sum++; vis[nxt]=true; nxt=a[nxt]; } //System.out.println(sum); ans=lcm(ans,BigInteger.valueOf(sum)); } System.out.println(ans); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> using namespace std; typedef __int128 ll; const int maxn=1e5+7; int a[maxn],vis[maxn],len[maxn]; vector <int > v; void print( ll x ) { if( x<0 ) x=-x,putchar('-'); if( x>9 ) print(x/10); putchar( x%10+'0' ); } void read(ll &x ) { x=0;int f=1;char s=getchar(); for( ;!isdigit(s);s=='-' && (f=-1),s=getchar()); for( ;isdigit(s);x=x*10+s-48,s=getchar()); x*=f; } ll lcm(ll a,ll b){ return a/__gcd(a,b)*b; } int main(){ int t,n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } ll len=0; ll ans=1; for(int i=1;i<=n;i++){ if(!vis[i]){ v.clear(); int j=i; while(!vis[j]){ vis[j]=1; v.push_back(j); j=a[j]; } len=v.size(); ans=lcm(ans,len); } } print(ans); return 0; }