Loading

polya计数

polya计数

总结

问题: 同构计数 \

bunside定理: 在置换g下染色方案不变数的平均值;公式:\(\frac{1}{|G|}\sum_{g\in G}C(g)\), 其中\(C(g)\) 是在染色方案在置换g下保持不变的方案的数目;不证; \

polya定理: \

polya定理是对Burnside定理求\(C(g)\)的优化,注意到置换中处于同一循环的元素应该保持染色相同,而不同循环的元素则互不影响。下面简单解释一下置换中的循环。 \

对于如下置换 g1\

1 2 3 4 5 \

3 2 1 5 4 \

那么由如下循环 (1,3)(2)(4,5),即要求(1,3)染色相同,(2)染色相同,(4,5) 染色相同。假设存在m中颜色,那么\(C(g1)=m^3\);由此可得polya公式: \

\(\frac{1}{|G|}\sum_{g\in G}{m^{c(g)}}\),其中\(c(g)\)表示置换g的循环次数(也称循环节的长度)

参考:
burnside定理可以看blog

入门题poj2409

分析

考虑旋转和反转两种置换,旋转的循环节长度为\(gcd(n,i) i=0,1,2..n-1\);
考虑翻转:分奇偶讨论对称轴即可

代码

#include<bits/stdc++.h>
using namespace std;

#define ll long long

int c,s;
int gcd(int a,int b){
    if(b==0) return a;
    return gcd(b,a%b);
}

ll polya(){
    ll ans = 0;
    for(int i=0;i<s;i++){
        ans+=(ll)pow(c,gcd(s,i));
    }
    if(s&1){//odd
        ans+=(ll)s*(ll)pow(c,s/2+1);
    }
    else{
        ans+=(ll)(s/2)*(ll)pow(c,s/2+1);
        ans+=(ll)(s/2)*(ll)pow(c,s/2);
    }
    return (ll)ans/(2*s);
}

int main(){
    while(cin>>c>>s){
        if(c==0&&s==0) break;
        if(c==0) return 0;
        if(s==0) return 1;
        cout<<polya()<<endl;
    }
    return 0;
}
posted @ 2019-06-25 15:03  fridayfang  阅读(198)  评论(0编辑  收藏  举报