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;
}

转载于:https://www.cnblogs.com/fridayfang/p/11082886.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值