[2020牛客暑期多校训练营第五场] E.Bogo Sort 大数+群论基础

题目链接 :E.Bogo Sort

前几天刚看过群论,所以今天这道题转换为群论后能立刻反应写出,只不过本题要求大数运算,所以用java写完A了。

题意

给你n个数的一种排列组合,问你通过题目给的排序算法,至少需要多少次变换能够转换为1~n的序列。
题目描述

题解

通过这个核心代码可以看出,题目给的算法就是一种置换,最初的为T,问你k为多少时, T k = e {T^k=e} ,e为单元置换也就是1,2,3…n。
Permutations POJ - 2369如出一辙
唯一不同的是需要对 1 0 n {10^n} 取模,n的范围 1 N 1 0 5 {1≤N≤10^5} ,所以一般的数据类型是无法存储 1 0 n {10^n} 这样大的数字。所以用java大数BigInteger可以解决此类问题。

代码

import java.math.BigInteger;
import java.util.*;
public class Main {
    public static int f[] = new int[100005];
    public static BigInteger cnt[] = new BigInteger[100005];
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        BigInteger r=BigInteger.ONE;
        for(int i=1;i<=n;i++)
            r=r.multiply(BigInteger.valueOf(10));
        for (int i = 1; i <= n; i++)
            f[i] = i;
        for(int i=1;i<=100000;i++)
            cnt[i]=BigInteger.ZERO;
        for (int i = 1; i <= n; i++) {
            int x;
            x = sc.nextInt();
            if (find(i) != find(x)) f[x] = i;
        }
        for (int i = 1; i <= n; i++)
            cnt[find(i)] = cnt[find(i)].add(BigInteger.ONE);
        BigInteger ans = BigInteger.ONE;
        for (int i = 1; i <= n; i++) {
            if (cnt[i]!=BigInteger.ZERO)
            {
                ans = lcm(ans, cnt[i]);
            }
        }
        System.out.println(ans.mod(r));
    }
 
    public static int find(int x) {
        if (x == f[x])
            return x;
        else
            return f[x] = find(f[x]);
    }
    public static BigInteger lcm(BigInteger a, BigInteger b) {
        return a.multiply(b).divide(a.gcd(b));
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44235989/article/details/107647009