题目链接:2020牛客暑期多校第五场E题-Bogo Sort
题意
给出一个置换 (p),问 (1sim n) 这 (n) 个数有多少种排列,能经过若干次 (p) 的置换后变成有序?答案对 (10^n) 取模。
思路
题意也等价于有序的 (1sim n) 经过 (p) 的若干次置换,能形成多少种不同的排列。
记置换 (P) 有 (z) 个环,长度分别为 (C_1,C_2,...,C_z),(1sim n) 分别经过 (x_1) 和 (x_2) 次置换后,记 (S_1={x_1\%C1,x_1\%C_2,...,x_1\%C_z},S_2={x_2\%C1,x_2\%C_2,...,x_2\%C_z}) ,当且仅当 (S_1 e S_2) ,形成的排列不同。
记 (L=lcm(C_1,C_2,...,C_z)) ,当 (|x_1-x_2| e ycdot L, yin N^*) ,有 (S_1 e S_2) 。显然最多有 (L) 个不同的 (x) ,满足 (|x_i-x_j| e ycdot L, iin[1,L],jin [1,L],i e j) ,即最多形成 (L) 种不同的排列,所以答案为 (L) 。
对于取模,实际上 (L) 肯定小于 (10^n) ,所以不用取模。令 (L'=prod_{i=1}^z C_i) ,显然 (L'ge L) ;由于 (sum_{i=1}^z C_i=n) ,可按如下方法构造出最大的 (L') :
[egin{cases}forall iin[1,z], C_i=2, &if n is even \ forall iin[1,z-1],C_i=2,Cz=3 &if n is oddend{cases} \ Downarrow \L'=egin{cases}2^{n/2}, &if n is even \2^{(n-3)/2}cdot 3 &if n is oddend{cases}
]
显然 (Lle L' lt 10^n) 。
代码实现
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int p[] = new int[n+10];
boolean vis[] = new boolean[n+10];
for (int i = 1; i <= n; i++) p[i] = sc.nextInt();
ArrayList<Integer> C = new ArrayList<Integer>();
for (int i = 1; i <= n; i++) {
int ci = 0, tmp = i;
while (!vis[tmp]) {
vis[tmp] = true;
ci++;
tmp = p[tmp];
}
if (ci > 0) C.add(ci);
}
BigInteger ans = BigInteger.ONE;
for (int ci : C) {
BigInteger g = ans.gcd(BigInteger.valueOf(ci));
ans = ans.multiply(BigInteger.valueOf(ci)).divide(g);
}
System.out.println(ans);
}
}