UESTC 1153 The Queen's New Necklaces (Burnside定理)

题目链接:http://acm.uestc.edu.cn/problem.php?pid=1153

题意:一个项链的珠子的颜色有若干种。每种颜色的珠子个数为Ai。求有多少种不同的项链?

思路:Burnside定理的描述是:

UESTC 1153 The Queen's New Necklaces (Burnside定理)_第1张图片

 

对于本题,G就是旋转0、1、2……n-1。那么我们需要计算旋转i时的不变元个数。对于旋转0度,是经典的排列组合的问题,即有可重复元素出现的排列问题.然后旋转i格,共有Gcd(n,i)个循环,每个循环中有N=n/gcd(n,i)个元素 (n表示小珠子总个数)。如果对于某种颜色的小珠子,它的个数不是N的整数倍,那么显然这种旋转下不存在不动点。如果存在,那么相当于A[i]/N个新的同颜色的小球拿去重新组成一个环的种类数,同样是上面的经典问题。如下图所示,n=10,i=5,三种小球,个数分别为2,4,4,则下面一种排列是不变元:

UESTC 1153 The Queen's New Necklaces (Burnside定理)_第2张图片

import java.io.*;
import java.util.*;
import java.math.*;
import java.text.*;

public class Main 
{
    static int Gcd(int a,int b)
    {
        return b==0?a:Gcd(b,a%b);
    }
    
    public static void main(String args[])
    {
        Scanner cin=new Scanner(System.in);   
        BigInteger f[]=new BigInteger[1005],ans,temp;
        int C;
        int i,j,k,tot,sum,n,a[]=new int[105],b[]=new int[105];
        f[0]=BigInteger.ONE;
        for(i=1;i<=1000;i++) f[i]=f[i-1].multiply(BigInteger.valueOf(i));
        C=cin.nextInt();
        while(C-->0)
        {
            n=cin.nextInt();
            sum=0;
            for(i=1;i<=n;i++)
            {
                a[i]=cin.nextInt();
                sum+=a[i];
            }
            ans=f[sum];
            for(i=1;i<=n;i++) ans=ans.divide(f[a[i]]);
            for(i=1;i<sum;i++)
            {
                k=sum/Gcd(sum,i);
                tot=0;
                for(j=1;j<=n;j++)
                {
                    if(a[j]%k!=0) break;
                    b[j]=a[j]/k;
                    tot+=b[j];
                }
                if(j<=n) continue;
                temp=f[tot];
                for(j=1;j<=n;j++) temp=temp.divide(f[b[j]]);
                ans=ans.add(temp);
            }
            System.out.println(ans.divide(BigInteger.valueOf(sum)));
        }
    }
}

  

你可能感兴趣的:(ide)