【BZOJ】1004: [HNOI2008]Cards(置换群+polya+burnside)
http://www.lydsy.com/JudgeOnline/problem.php?id=1004
学习了下polya计数和burnside引理,最好的资料就是:《Pólya 计数法的应用》 --陈瑜希
burnside:
$$等价类的个数=\frac{1}{|G|}\sum_{i=1}^{s}D(a_i), a_i \in G$$其中$D(a_i)=a_i置换中染色后不变的方案$
而polya:
$$D(a_i)=k^{C(a_i)},其中C(a_i)是a_i的循环节个数$$证明很简单,要让染色不变,那么每个循环节的颜色一定要一样。
但是在这一题,颜色数目不是无限的,那么我们可以考虑DP
对于每个置换$a_i$,有循环节$cnt$个,每个循环节有$s[x]$个元素,那么我们用背包思想计数即可,设f[r,b,g]表示1~i的循环节用了r个红色,b个蓝色,g个绿色,有
f[r,b,g]=f[r-s[i], b, g]+f[r, b-s[i], g]+f[r, b, g-s[i]]
然后注意,因为是置换群,所以要满足群的定义,即题目虽然满足了逆元“对每种洗牌法,都存在一种洗牌法使得能回到原状态”,而封闭性和结合律只要是置换群都满足,所以还缺一个单位元的性质,因此我们要将单位元加进去再计数
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
#define rep(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define read(a) a=getint()
#define print(a) printf("%d", a)
#define dbg(x) cout << (#x) << " = " << (x) << endl
#define error(x) (!(x)?puts("error"):0)
inline const int getint() { int r=0, k=1; char c=getchar(); for(; c<'0'||c>'9'; c=getchar()) if(c=='-') k=-1; for(; c>='0'&&c<='9'; c=getchar()) r=r*10+c-'0'; return k*r; }const int N=65;
int a[N], s[N], vis[N], R, B, G, n, m, f[22][22][22], p, ans;
void add(int &a, const int &b) { a=(a+b)%p; a=(a+p)%p; }
int mpow(int a, int b) {int ret=1;for(; b; a=(a*a)%p, b>>=1) if(b&1) ret=(ret*a)%p;return ret;
}
int getans() {CC(f, 0); CC(s, 0); CC(vis, 0); int cnt=0;for1(i, 1, n) if(!vis[i]) { ++cnt; for(int x=i; !vis[x]; x=a[x]) vis[x]=1, ++s[cnt]; }f[0][0][0]=1;for1(i, 1, cnt) for3(r, R, 0) for3(b, B, 0) for3(g, G, 0) {if(r-s[i]>=0) add(f[r][b][g], f[r-s[i]][b][g]);if(b-s[i]>=0) add(f[r][b][g], f[r][b-s[i]][g]);if(g-s[i]>=0) add(f[r][b][g], f[r][b][g-s[i]]);}return f[R][B][G];
}
int main() {read(R); read(B); read(G); read(m); read(p); n=R+B+G;for1(i, 1, m) { for1(i, 1, n) read(a[i]); add(ans, getans()); }for1(i, 1, n) a[i]=i;add(ans, getans());ans*=mpow(m+1, p-2);printf("%d\n", ans%p);return 0;
}
Description
小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红色,Sb张蓝色,Sg张绝色.他又询问有多少种方案,Sun想了一下,又给出了正确答案. 最后小春发明了M种不同的洗牌法,这里他又问Sun有多少种不同的染色方案.两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方法可以使用多次)洗成另一种.Sun发现这个问题有点难度,决定交给你,答案可能很大,只要求出答案除以P的余数(P为质数).
Input
第一行输入 5 个整数:Sr,Sb,Sg,m,p(m<=60,m+1<p<100)。n=Sr+Sb+Sg。接下来 m 行,每行描述
一种洗牌法,每行有 n 个用空格隔开的整数 X1X2...Xn,恰为 1 到 n 的一个排列,表示使用这种洗牌法,
第 i位变为原来的 Xi位的牌。输入数据保证任意多次洗牌都可用这 m种洗牌法中的一种代替,且对每种
洗牌法,都存在一种洗牌法使得能回到原状态。
Output
不同染法除以P的余数
Sample Input
2 3 1
3 1 2
Sample Output
HINT
有2 种本质上不同的染色法RGB 和RBG,使用洗牌法231 一次可得GBR 和BGR,使用洗牌法312 一次 可得BRG 和GRB。
100%数据满足 Max{Sr,Sb,Sg}<=20。
Source
【BZOJ】1004: [HNOI2008]Cards(置换群+polya+burnside)相关推荐
- 置换群burnside引理(bzoj 1004: [HNOI2008]Cards)
置换群: 看半天置换群表示并看不懂QAQ 但顾名思义是置换组成的群 其实不用看懂也行,就拿简单的例子来说吧 有一个序列s = {1, 2, 3, 4, 5, 6} 和一个变换规则t = {2, 3, ...
- BZOJ 1004: [HNOI2008]Cards [Polya 生成函数DP]
传送门 题意:三种颜色,规定使用每种颜色次数$r,g,b$,给出一个置换群,求多少种不等价着色 $m \le 60,\ r,g,b \le 20$ 咦,规定次数? <组合数学>上不是有生成 ...
- bzoj 1004: [HNOI2008]Cards
/**************************************************************Problem: 1004User: lxy8584099Language ...
- 置换群Polya定理(poj 2409: Let it Bead)
可以先看 置换群burnside引理(bzoj 1004: [HNOI2008]Cards) Polya定理公式(必须在没有限制下才能使用此公式): 其中|G|为总置换数,m表示可用的颜色数,c(gi ...
- [HNOI2008]Cards
1004: [HNOI2008]Cards Time Limit: 10 Sec Memory Limit: 162 MB [Submit][Status][Discuss] Description ...
- P1446 [HNOI2008]Cards
P1446 [HNOI2008]Cards 题意: 有n张牌,染三种颜色,每种颜色规定数目,给出m种不同的洗牌方法.两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法,而每种方 ...
- [bzoj1004][HNOI2008]Cards
[bzoj1004][HNOI2008]Cards 标签: 置换 Burnside引理 题目链接 扯淡 题目中说了这样一句话 两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌法 ...
- BZOJ 1005: [HNOI2008]明明的烦恼
BZOJ 1005: [HNOI2008]明明的烦恼 Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在 任意两点间连线 ...
- 置换群和Burnside引理,Polya定理
定义简化版: 置换,就是一个1~n的排列,是一个1~n排列对1~n的映射 置换群,所有的置换的集合. 经常会遇到求本质不同的构造,如旋转不同构,翻转交换不同构等. 不动点:一个置换中,置换后和置换前没 ...
最新文章
- Java中ArrayList源码分析
- 将深度学习技术应用到实际项目
- Sklearn(v3)——SVM理论(1)
- C#操作MySQL数据库的简单例子
- 全球及中国综艺节目产业营销策略分析及创新格局规划建议报告2021-2027年
- C语言程序设计 函数递归调用示例
- boost::mp11::mp_inherit相关用法的测试程序
- Linux驱动之Input子系统要点分析
- bootstrap的表单验证 vue_第45天:Web表单
- Java反序列化json内存溢出_fastJson与一起堆内存溢出'血案'
- 准确估计透明物体的 3D 姿态:机器人收集 + Keypose 算法
- 太长的sql怎么分析_因为ESR, 我一定要推荐你这款 SQL 神器
- .net中的装箱与拆箱!
- ubuntu12.04安装配置opensips,搭建voip服务器
- python 图片文字转换成word_如何基于python把文字图片写入word文档
- 你用过猿如意吗?猿如意可以使用ChatGPT哦,这里详细介绍了猿如意的功能,为什么我建议你使用猿如意,来看看吧
- std::uninitialized_copy::_Unchecked_iterators::_Deprecate
- Day25 - Event Capture, Propagation, Bubbling and Once
- 关于坯布的面料克重问题
- PHP是世界上最好语言吗?
热门文章
- 性能优化之MySQL调优篇
- 计数排序Counting sort
- WDCP管理面板安装启动EXIF、bcmath完整步骤
- [ios2] ios使用自带git respository管理项目 【转】
- VC的MFC中重绘函数的使用总结(整理)
- cpp之间函数引用和类引用的方法
- linux 关掉蓝牙自动,如何在Ubuntu 14.04中默认关闭蓝牙,蓝牙
- java actor和线程有什么区别_Scala Actor与java并发编程的区别
- 标识人脸程序matlab,Matlab人脸识别基础源程序
- apache camel 相关配置_Apache Camel的Java编程入门指南