polya 计数法,burnside定理 学习小结

学习笔记】Burnside引理,Pólya定理及其应用 好东西+1 阅读详情

polya 计数法,burnside定理 学习小结


转载自:http://hi.baidu.com/%B1%BF%D0%A1%BA%A2_shw/blog/item/89fd091055caf51db9127bc8.html


记得最早接触这类题目还是去年这个时候,当时看了点书,做了几个水题,就以为自己懂了。
后来发现自己还是根本没有理解。最近简单复习了下,又做了几道相关的题目。

但现在真的发现这个算法自己还是没有完全理解,只会简单地套公式,很多难的题目现在还是做不来,先整理一下,方便以后再复习吧。

ps : 感谢 cuiaoxiang 及 AekdyCoin 给我的一些帮助。

先贴个模板:
 int ans = 0;
        for (int i = 1; i <= n; i++) if (n % i == 0) {
            ans += fun(c, i) * euler(n / i);
        }
        if (n & 1) ans += n * fun(c, n / 2 + 1);
        else ans += n / 2 * (fun(c, n / 2) + fun(c, n / 2 + 1));
        cout << ans / (2 * n) << endl;

这个就是最裸的polya,用这个模板可以过:pku2409 【Let it Bead】

当n比较大的时候,这样直接枚举n就有点太暴力了,可以把n整数分解,直接去枚举他的因子即可。


再贴个模板:

 void dfs(int step, int now, int n) {
    if (step >= cnt + 1) {
        ans = (ans + fun(n % mod, now - 1) * euler(n / now) % mod) % mod;
        return;
    }
    for (int i = 0, t = 1; i <= c[step]; t *= p[step], i++)
        dfs(step + 1, now * t, n);
}
用这个模板可以过: pku2154 【Color】

下面推荐一些简单的稍加变形的题目:
ps : 以下代码中 Prime() 为求素数,divide() 为整数分解,euler() 为求欧拉函数,fun()为求快速幂乘,matrix 为一个矩阵类(重载过乘号)。
pku2888  【Magic Bracelet】

这道题原来写过一个解题报告,具体见这里吧:【pku2888 (有限制条件的polay问题)】

hdu2865  【 Birthday Toy】


这题和上一题差不多,都是在颜色的关系上做了限制,要求一个环上相邻2个珠子的颜色不能相同,推出递推公式,用矩阵乘法就可以了。

 int n, m;
long long ans;


long long cal(int k) {
    long long cc = m - 1, ret;
    if (k == 1) return 0;
    if (k == 2) return cc * (cc - 1) % mod;
    k -= 2;
    matrix a, b;
    a.mat[0][0] = 0;
    a.mat[0][1] = 1;
    a.mat[1][0] = cc - 1;
    a.mat[1][1] = cc - 2;
    FF(i, 0, 1) FF(j, 0, 1) b.mat[i][j] = (i == j) ? 1 : 0;
    while (k) {
        if (k & 1) b = b * a;
        a = a * a;
        k /= 2;
    }
    ret = (b.mat[1][1] * cc % mod) * (cc - 1) % mod;
    return ret;
}


void dfs(int step, int now) {
    if (step >= cnt + 1) {
        ans = (ans + (long long)cal(now) * euler(n / now) % mod) % mod;
        return;
    }
    for (int i = 0, t = 1; i <= c[step]; i++, t *= p[step])
        dfs(step + 1, now * t);
}


int main(int argc, char** argv) {


    Prime();
    while (scanf("%d%d", &n, &m) != EOF) {
        divide(n);
        ans = 0;
        dfs(1, 1);
        ans = ans * fun(n, mod - 2) % mod;
        ans = ans * m % mod;
        printf("%d\n", ans);
    }


    return (EXIT_SUCCESS);
}
hdu3441  【 Rotation】


这题的设计还是很巧妙的,用了2次burnside,这题的关键在于 a 很大,不能直接枚举 b ,但其中b * b = a * a - 1,转化为分解(a + 1) 和 (a - 1),其他的都差不多了。

 long long a, c, n, m, temp, ans;

void dfs_t(int step, long long now) {
    if (step >= p1[0] + 1) {
        temp = (temp + fun(m % mod, now) * euler(n / now) % mod) % mod;
        return;
    }
    for (long long i = 0, t = 1; i <= c1[step]; t *= p1[step], i++)
        dfs_t(step + 1, now * t);
}


void dfs(int step, long long now) {
    if (step >= p1[0] + 1) {
        long long b = now;
        m = fun(c % mod, b * b);
        m += fun(c % mod, ((b * b + 3) / 4)) * 2 % mod;
        m += fun(c % mod, ((b * b + 1) / 2));
        m %= mod;
        m = m * inv_4 % mod;
        n = (a * a - 1) / (b * b);
        temp = 0;
        dfs_t(1, 1);
        temp = temp * fun(n % mod, mod - 2) % mod;
        temp = temp * c % mod;
        ans = (ans + temp) % mod;
        return;
    }
    for (long long i = 0, t = 1; 2 * i <= c1[step]; t *= p1[step], i++) {
        c1[step] -= 2 * i;
        dfs(step + 1, now * t);
        c1[step] += 2 * i;
    }
}


void cal() {
    divide(a - 1, p1, c1);
    divide(a + 1, p2, c2);
    for (int i = 1; i <= p2[0]; i++) {
        bool f = false;
        for (int j = 1; j <= p1[0]; j++) if (p2[i] == p1[j]) {
            c1[j] += c2[i];
            f = true;
            break;
        }
        if (f == true) continue;
        p1[0]++;
        p1[p1[0]] = p2[i];
        c1[p1[0]] = c2[i];
    }
    dfs(1, 1);
}


int main(int argc, char** argv) {
    int T, ca = 0;


    scanf("%d", &T);
    Prime();
    while (T--) {
        scanf("%lld%lld", &a, &c);
        ans = 0;
        if (a == 1) ans = c;
        else cal();
        printf("Case %d: %d\n", ++ca, ans);
    }


    return (EXIT_SUCCESS);
}


hdu2481  【 Toy】
这题的难点同样是在一个确定的置换下如何确定合法的方案数。
这题感觉稍微有点难,我是参考一个大牛的解题报告后才做出来的。
具体参见这里吧:【解题报告】
long long cal(long long k) {
    matrix a, c;
    FF(i, 0, 2) FF(j, 0, 2) c.mat[i][j] = (i == j) ? 1 : 0;
    a.mat[0][0] = 0;
    a.mat[0][1] = 1;
    a.mat[0][2] = 0;
    a.mat[1][0] = -1;
    a.mat[1][1] = 3;
    a.mat[1][2] = 0;
    a.mat[2][0] = 0;
    a.mat[2][1] = 1;
    a.mat[2][2] = 1;

    k -= 1;
    while (k) {
        if (k & 1) c = c * a;
        a = a * a;
        k /= 2;
    }
    long long f = c.mat[1][1] % mod;
    long long g = 2 * c.mat[2][1] % mod;
    return (g + f) % mod;
}


void dfs(int step, int now) {
    if (step >= cnt + 1) {
        ans = (ans + mult((long long)cal(now), euler(n / now))) % mod;
        return;
    }
    for (int i = 0, t = 1; i <= c[step]; i++, t *= p[step])
        dfs(step + 1, now * t);
}


int main(int argc, char** argv) {

    Prime();
    while (cin >> n >> m) {
        mod = n * m;
        divide(n);
        ans = 0;
        dfs(1, 1);
        ans = (ans / n % m + m) % m;
        cout << ans << endl;
    }


    return (EXIT_SUCCESS);
}


还有不少比较难的题目,实在做不来了,等以后做了再补上吧。
Burnside引理和Polya定理详解(适合零基础) 声明:本知识点为帮助大家更好地理解置换群论这一抽象的内容,一些定义中掺杂了撰写者自身的理解,和严格的数学定义有些出入,基本为数学定义的缩小解释和限制解释。 另外,统一一些符号的使用。 对集合A,|A|表示A中元素的个数 对命题p,若为真,则[p]=1;若为假,则[p]=0。如[1>2]=0,[gcd(3,5)=1]=1 对一个群,e表示该群的单位元,g−1g^{-1}g−1表示群中元素ggg的逆元 =问题描述= 一个n个点的环,用n种颜色去染。求有多少种本质不同的染色方案。 两种染色方案相同当且仅当通 阅读详情

相关推荐

【组合数学】通俗解释 Burnside引理和Polya定理

文章目录Burnside引理和Polya定理Burnside引理定义:Burnside例子解释Polya定理 Burnside引理和Polya定理 对于图形来说,如果通过旋转,图像能达到其他图像的效果,这叫做本质上一样。 Burnside的目的是,我们能有多少种排列方案,求的是一个方案的数量num。 Burnside引理定义: 反正直接让我看这个定义…我是看不懂…所以还是直接上例子吧。 Burnside例子解释 所以!!!例子套用Burnside引理就是 L = (16+2+4+2)/4 =

火火的博客 3332

伯恩赛德定理(集合S的 置换群 诱导出来的等价关系 对集合S 划分 得到的 等价类个数)

前言:仅个人小记。 定理内容 由 S 的置换群 <G, >

Zetaa的博客 3750

polya计数学习小结

最近半个月以来一直在看《组合数学》,马马虎虎也算翻完了,理解的也很浅,接下来的一个月中,我将把主要精力放在做数学题上同时巩固总结这一 个月以来所学的数论组合数学知识。那就先从Polya计数法开始吧。 Burnside定理: 首先介绍一下有关置换群的一些知识。 置换: 设

xiaohuan1991的专栏 8486

Burnside引理和polay计数学习笔记

本文参考自:https://blog.csdn.net/lyc1635566ty/article/details/52545355   首先由一个 2 * 2的矩阵里染色问题引出:   在一个 2 * 2的矩阵中染色,问有多少种染色方法,旋转后相同的算一种。   显然穷举的话,有以上种,但是不难发现,(2,3,4,5)是同一种,(6,7)是同一种,(8,9,10,11)是一种,(12,13,14...

桃夭丶的博客 418

Polya计数法浅析&caioj1475【Polya计数法】项链上的珠子

Polya计数法 最近学习了一个很高深的算法QAQ,它就是polya计数法那么我们就来学习一下这个算法吧~~~请先看下面这道例题: 【例题】 对2*2的方阵用黑白两种颜色涂色,问能得到多少种不同的图像?经过旋转使之吻合的两种方案,算是同一种方案。 【问题分析】 由于该问题规模很小,我们可以先把所有的涂色方案列举出来。 一个2*2的方阵的旋转方法一共有4种:旋转0度、旋

LJH_KOQI的博客 1392

POJ 2409 Let it Bead【polya 计数法burnside定理

POJ 2409 Let it Bead 算法核心:polya 计数法burnside定理http://blog.sina.com.cn/s/blog_6f71bea30100opru.html 大意: 珠子的颜色有c种,问可组成多少种长度为s的项链? 分两种情况讨论:旋转:n种旋转方法每种旋转i个格(1<=i<=n)循环结有gcd(i,n)个翻转: (1)这种是...

a48634331的博客 183

burnside引理+polya计数法小结

WC上wwwwodddd讲的整数和多项式相关里面最后又burnside引理的一部分 被生成函数调戏疯了的我突然断线重连 坐在礼堂最后一排的沙发位上和老黄人疯狂口糊 不过听课的时候想的不是很细,重新整理了一发 大概就是 本质不同的方案数=1置换个数∑cnti=0在置换i下不变的方案数本质不同的方案数=\frac{1}{置换个数}\sum_{i=0}^{cnt}在置换i下不变的方案数 至

HbFS- 2252

polya|burnside定理的一些总结

基于正方形的置换:(hdu 1812) 旋转只有 0,90,180,270度三种旋法。 旋0度,则置换的轮换数为n*n 旋90度,n为偶数时,则置换的轮换数为n*n/4,n为奇数,则置换的轮换数为(n*n-1)/4+1 旋180度,n为偶数时,则置换的轮换数为n*n/2,n为奇数,则置换的轮换数为(n*n-1)/2+1 旋270度,n为偶数时,则置换的轮换数为n*n/4,n为奇数,则置换

ACM之梦 1549

菜鸟系列——polya计数法

菜鸟就要老老实实重新学起: Burnside引理,polya计数法Burnside引理: 1/|G|*(C(π1)+C(π2)+C(π3)+.....+C(πn)); C(π):指不同置换下的等价类数。例如π=(123)(3)(45)(6)(7),X={1,2,3,4,5,6,7};那么C(π)={3,6,7}共3个等价类。 Polya定理: 1/|G|*(mC(π1)+m

MyWorld 2214

burnside引理与Polya定理计数法

Text我们将一个集合到它自身的一个一一映射称为一个置换对于集合[1,2,3,4] (13223441)\begin{pmatrix} 1 & 2 & 3 &4\\ 3 & 2 & 4 &1\\ \end{pmatrix} 就是一个置换,把1换成3,2换成4,3换成2,4换成1我们也可以将其写成循环节的乘积的形式 因为1到3,3到4,4到1这是一个循环节 2自己构成一个循环节 (1,3,4

Never give in. 818

群论 polya burnside

http://www.elijahqi.win/archives/3388 群论 什么是群? 元素和建立在元素上的二元运算构成的代数系统 如何判定是否是一个群? 要求满足四条群公理 设(S,+)(S,+)(S,+ )为群满足如下公理 封闭性 ∀x,y∈S,x+y∈S∀x,y∈S,x+y∈S\forall x,y \in S,x+y \in S 结合率 ∀a,b,c∈S(a+b)+...

Elijahqi 362

抽象代数----轨道稳定子定理burnside定理

linux-0.11调试教程 1733

如何用 Burnside 引理解决项链问题

对每个珠子进行标号,虽然可以选择两种颜色,但某些排列组合的项链经过旋转种类是一样的,比如如下两种:接下来我们看看项链可以经过哪些变换,以及如果不考虑变换,静态的项链有多少种不同的染色方案。项链的变换其实就是刚性变换:旋转和反射。容易知道六颗珠子的项链有 6 种旋转(顺时逆时取其一)和 6 种反射(6 条对称轴),一共 12 种变换,如下图:C6320C63​20种不难想象,经过旋转和反射后,最终只有三种形态的项链,也就是:这里像不像有机物?

zzrisme的博客 2997

Burnside引理与Polya定理

解决本质不同方案数 参考博客 "引理"和"定理"并没有什么区别 Burnside引理 ∣X/G∣=∑g∈G∣Xg∣∣G∣|X/G|=\frac{\sum_{g\in G}|X^g|}{|G|}∣X/G∣=∣G∣∑g∈G​∣Xg∣​ 定义 符号 定义 解释 XXX A,BA,BA,B为两个有限集合,X=BAX=B^AX=BA表示所有从AAA到BBB的映射 相当于给小球集合AAA中的每个求涂上颜色集合BBB中的颜色 GGG 作用在AAA上的置换群 字面意思 X/GX/GX/G XX

00ffcc的博客 358

Burnside引理&Pólya定理

Burnside's lemma 引例 题目描述 一个由2*2方格组成的正方形,每个格子上可以涂色或不涂色, 问共有多少种本质不同的涂色方案。 (若两种方案可通过旋转互相得到,称作本质相同的方案) 解法 每个格子可以涂色,可以不涂色,共有16种方案。将16种方案编号。 把本质相同的方案合并: 方案1:{1},方案2:{2}, 方案3:{3,4,5,6},方案4:{7,8,9,10},...

banchangyue3928的博客 782

(组合数学笔记)Pólya计数理论_Part.4_Burnside引理

Burnside引理

zorchp 1034

解题报告 (五) Burnside引理和Polya定理

Burnside引理   笔者第一次看到Burnside引理那个公式的时候一头雾水,找了本组合数学的书一看,全是概念。后来慢慢从Polya定理开始,做了一些题总算理解了。本文将从最简单的例子出发,解释Burnside引理和Polya定理。然后提供一些自己做过的和上述定理相关的题目和解题报告。   Burnside引理是为了解决m种颜色给n个对象染色的计数问题。  【例题1】如图1所示,2×2...

英雄哪里出来 31万+
上一篇: 数学类题目小结
下一篇: 这是计算机科学
sumi
博客等级 码龄15年 189粉丝 210原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值