zoukankan      html  css  js  c++  java
  • UVA11255 Necklace [Polya定理]

    NecklaceNecklace


    Descriptionmathcal{Description}
    见上方链接.


    Solutionmathcal{Solution}

    • 先考虑 旋转同构,
      设顺时针旋转 kk 个, 共有 num=gcd(k,N)num=gcd(k,N) 个循环节, 每个循环节的长度都为 size=Ngcd(k,N)size=frac{N}{gcd(k,N)},
      要成功染色, 必须满足 a%size=b%size=c%size=0a\%size=b\%size=c\%size=0 才可以成功染色,
      a,b,ca,b,c 同时除 sizesize,
      染色的方案数Ca+b+caCb+cbC_{a+b+c}^a*C_{b+c}^b,

    • 再考虑 对称同构,
      1.若 NN奇数,

      • a,b,ca,b,c 颜色必须为 121奇2偶, 否则无解.
      • 若满足上述条件, 则设 aa 为奇数, 将 aa11后, 三者除 22,
        方案数NCa+b+caCb+cbN*C_{a+b+c}^{a}*C_{b+c}^b .

      2.若 NN偶数,

      • 对称轴穿过两个点,
        1. a,b,ca,b,c 两奇一偶,
          将两个奇数减去 11, 三者除22, 方案数NCa+b+caCb+cbN*C_{a+b+c}^a*C_{b+c}^b.
        2. a,b,ca,b,c 全部为偶数, 三者除22, 方案数N2Ca+b+caCb+cbfrac{N}{2}*C_{a+b+c}^a*C_{b+c}^b.
      • 对称轴不过点,要满足 a,b,ca,b,c 均为偶数
        a,b,ca,b,c 全部除 22, 方案数N2Ca+b+caCb+cbfrac{N}{2}*C_{a+b+c}^a*C_{b+c}^b

    将所有方案加起来后 除 总置换数 2(a+b+c)2(a+b+c) 即可.


    Codemathcal{Code}

    #include<cstdio>
    #define reg register
    typedef long long ll;
    
    int a, a1;
    int b, b1;
    int c, c1;
    int N;
    ll C[50][50];
    
    int gcd(int a, int b){ return !b?a:gcd(b, a%b); }
    
    ll Calc(){ return C[a1+b1+c1][a1] * C[b1+c1][b1]; }
    
    void Init(){ 
            C[0][0] = 1;
            reg int j;
            for(reg int i = 1; i <= 45; i ++)
                    for(j = 1, C[i][0]=1; j <= i; j ++) C[i][j] = C[i-1][j] + C[i-1][j-1];
    }
    
    void Work(){
            scanf("%d%d%d", &a, &b, &c);
            N = a+b+c;
            ll Ans = 0;
            for(reg int k = 0; k < N; k ++){
                    int size = N/gcd(k, N);
                    if(a%size || b%size || c%size) continue ;
                    a1 = a/size, b1 = b/size, c1 = c/size;
                    Ans += Calc();
            }
            if(N & 1){
                    int cnt = (a&1) + (b&1) + (c&1);
                    if(cnt == 1){
                            if(a & 1) a1 = a-1>>1, b1 = b>>1, c1 = c>>1;
                            else if(b & 1) a1 = a>>1, b1 = b-1>>1, c1=c>>1;
                            else a1 = a>>1, b1 = b>>1, c1 = c-1>>1;
                            Ans += N * Calc();
                    }
            }else{
                    int cnt = (a&1) + (b&1) + (c&1);
                    if(!cnt){
                            a1 = a>>1, b1 = b>>1, c1 = c>>1;
                            Ans += N*Calc();
                    }else if(cnt == 2){
                            if(a%2 == 0) a1 = a>>1, b1 = b-1>>1, c1 = c-1>>1;
                            else if(b%2 == 0) a1 = a-1>>1, b1 = b>>1, c1 = c-1>>1;
                            else a1 = a-1>>1, b1 = b-1>>1, c1 = c>>1;
                            Ans += N*Calc();
                    }
            }
            printf("%lld
    ", Ans/2/N);
    }
    
    int main(){
            Init();
            int T;
            scanf("%d", &T);
            while(T --) Work();
            return 0;
    }
    
    
  • 相关阅读:
    设计模式之工厂模式(Factory Pattern)用C++实现
    读书笔记之Effective C++ 1.让自己习惯C++
    LeetCode之RemoveDuplicates扩展
    一致性哈希(Consistent Hashing)原理和实现(整理)
    LeetCode之Remove Duplicates from Sorted Array
    C++小结
    HTTP、HTTP1.0、HTTP1.1、HTTP2.0——笔记
    《趣谈网络协议》——问答笔记
    技术源于生活(头脑风暴)
    解决:未能加载文件或程序集“System.Web.Http, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822587.html
Copyright © 2011-2022 走看看