zoukankan      html  css  js  c++  java
  • UVA 11255 Necklace

    带颜色数限制的polya计数。

    其实感觉一样了。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 50
    using namespace std;
    long long t,col[5],c[maxn][maxn],n;
    long long gcd(long long a,long long b) 
    {
        if (!b) return a;
        return gcd(b,a%b);
    }
    void get_table()
    {
        c[0][0]=1;
        for (long long i=1;i<=40;i++)
        {
            c[i][0]=1;
            for (long long j=1;j<=40;j++)
                c[i][j]=c[i-1][j-1]+c[i-1][j];
        }
    }
    long long circ()
    {
        long long ret=0;
        for (long long i=0;i<n;i++)
        {
            long long d=gcd(i,n),x=n/d,base=1;
            if ((col[1]%(n/d)) || (col[2]%(n/d)) || (col[3]%(n/d))) continue;
            for (long long j=1;j<=3;j++)
            {
                base*=c[d][col[j]/x];
                d-=col[j]/x;
            }
            ret+=base;
        }
        return ret;
    }
    long long reflect()
    {
        long long ret=1,ret1=1,ret2=1;
        if (n&1)
        {
            long long cols[5];
            if ((col[1]&1) && (col[2]&1) && (col[3]&1)) return 0;
            for (long long i=1;i<=3;i++) {cols[i]=col[i];if (cols[i]&1) cols[i]--;}
            long long sum=n/2;
            for (long long i=1;i<=3;i++)
            {
                ret*=c[sum][cols[i]/2];
                sum-=cols[i]/2;
            }
            return ret*n;
        }
        else
        {
            long long cnt=0,cols[5];
            for (long long i=1;i<=3;i++) {cnt+=(col[i]&1);cols[i]=col[i];}
            if (cnt==2)
            {
                for (long long i=1;i<=3;i++) if (cols[i]&1) cols[i]--;
                long long sum=(n-2)/2;
                for (long long i=1;i<=3;i++)
                {
                    ret1*=c[sum][cols[i]/2];
                    sum-=cols[i]/2;
                }
                ret1*=(n/2);ret1*=2; 
            }
            else
            {
                ret1=0;
                for (long long i=1;i<=3;i++)
                {
                    long long base=1,cols[5],sum=(n-2)/2;
                    for (long long j=1;j<=3;j++) cols[j]=col[j];
                    cols[i]-=2;
                    for (long long j=1;j<=3;j++)
                    {
                        base*=c[sum][cols[j]/2];
                        sum-=cols[j]/2;
                    }
                    ret1+=base;
                }
                ret1*=(n/2);
            }
            if (!cnt)
            {
                long long sum=n/2;
                for (long long i=1;i<=3;i++)
                {
                    ret2*=c[sum][cols[i]/2];
                    sum-=cols[i]/2;
                }
                ret2*=(n/2);
            }
            else ret2=0;
            return ret1+ret2;
        }
    }
    void work()
    {
        scanf("%lld%lld%lld",&col[1],&col[2],&col[3]);
        n=col[1]+col[2]+col[3];
        printf("%lld
    ",(circ()+reflect())/(2*(col[1]+col[2]+col[3])));
    }
    int main()
    {
        get_table();
        scanf("%lld",&t);
        for (long long i=1;i<=t;i++) work();
        return 0;
    }
  • 相关阅读:
    利用Hexo搭建个人博客-环境搭建篇
    Appium的安装-MAC平台
    alias指令:设置命令别名
    Android学习——第一个NDK程序
    Android学习——windows下搭建Cygwin环境
    Android学习——windows下搭建NDK_r9环境
    Win7&Ubuntu12.04 双系统引导问题
    Android学习第三天-签名常用命令
    Android学习第三天-打包常用命令
    Android学习第二天-android常用命令
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6290015.html
Copyright © 2011-2022 走看看