UVA 11255 Necklace

UVA_11255

    应用burnside引理,关键在于对于每种置换求出不动方案的种数。

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    static int MAXD = 50;
    static Scanner cin = new Scanner(System.in);
    static int N, P, pn;
    static int[] a = new int[5], b = new int[5], prime = new int[MAXD], p = new int[MAXD];
    static boolean[] isprime = new boolean[MAXD];
    static BigInteger[] fac = new BigInteger[MAXD];
    static BigInteger ans;
    public static void main(String[] args) {
        prepare();
        int t = cin.nextInt();
        while(t != 0)
        {
            -- t;
            init();
            solve();
        }
    }
    static void prepare()
    {
        int i, j, k = 40;
        fac[0] = fac[1] = new BigInteger("1");
        for(i = 2; i <= k; i ++)
            fac[i] = fac[i - 1].multiply(BigInteger.valueOf(i));
        for(i = 0; i <= k; i ++)
            isprime[i] = true;
        P = 0;
        for(i = 2; i <= k; i ++)
            if(isprime[i])
            {
                prime[P ++] = i;
                for(j = i * i; j <= k; j += i)
                    isprime[i] = false;
            }
    }
    static void init()
    {
        int i;
        N = 0;
        for(i = 0; i < 3; i ++)
        {
            a[i] = cin.nextInt();
            N += a[i];
        }
        divide(N);
    }
    static void divide(int n)
    {
        int i;
        pn = 0;
        for(i = 0; i < P && prime[i] * prime[i] <= n; i ++)
            if(n % prime[i] == 0)
            {
                p[pn ++] = prime[i];
                while(n % prime[i] == 0)
                    n /= prime[i];
            }
        if(n > 1)
            p[pn ++] = n;
    }
    static int euler(int n)
    {
        int i, ans = n;
        for(i = 0; i < pn; i ++)
            if(n % p[i] == 0)
                ans = ans / p[i] * (p[i] - 1);
        return ans;
    }
    static void solve()
    {
        ans = new BigInteger("0");
        dfs(0, 1, N);
        if(N % 2 == 1)
        {
            for(int i = 0; i < 3; i ++)
            {
                for(int j = 0; j < 3; j ++)
                    b[j] = a[j];
                -- b[i];
                if(b[i] < 0)
                    continue;
                ans = ans.add(calculate(2).multiply(BigInteger.valueOf(N)));
            }
        }
        else
        {
            for(int i = 0; i < 3; i ++)
                b[i] = a[i];
            ans = ans.add(calculate(2).multiply(BigInteger.valueOf(N / 2)));
            for(int i = 0; i < 3; i ++)
                for(int j = 0; j < 3; j ++)
                {
                    for(int k = 0; k < 3; k ++)
                        b[k] = a[k];
                    -- b[i];
                    -- b[j];
                    if(b[i] < 0 || b[j] < 0)
                        continue;
                    ans = ans.add(calculate(2).multiply(BigInteger.valueOf(N / 2)));
                }
        }
        ans = ans.divide(BigInteger.valueOf(2 * N));
        System.out.println(ans);
    }
    static BigInteger calculate(int m)
    {
        int i, n = 0;
        BigInteger ans = new BigInteger("1");
        for(i = 0; i < 3; i ++)
        {
            if(b[i] % m != 0)
                return BigInteger.ZERO;
            b[i] /= m;
            n += b[i];
        }
        for(i = 0; i < 3; i ++)
        {
            ans = ans.multiply(comb(n, b[i]));
            n -= b[i];
        }
        return ans;
    }
    static void dfs(int cur, int v, int x)
    {
        int i, cnt = 0, t = 1;
        if(cur == pn)
        {
            for(i = 0; i < 3; i ++)
                b[i] = a[i];
            ans = ans.add(calculate(N / v).multiply(BigInteger.valueOf(euler(N / v))));
            return ;
        }
        while(x % p[cur] == 0)
        {
            ++ cnt;
            x /= p[cur];
        }
        for(i = 0; i <= cnt; i ++)
        {
            dfs(cur + 1, v * t, x);
            t *= p[cur];
        }
    }
    static BigInteger comb(int n, int m)
    {
        return fac[n].divide(fac[m]).divide(fac[n - m]);
    }
}
原文地址:https://www.cnblogs.com/staginner/p/2512507.html