【BZOJ1004】Cards(组合数学,Burnside引理)
【BZOJ1004】Cards(组合数学,Burnside引理)
题面
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
1 1 1 2 7
2 3 1
3 1 2
Sample Output
2
HINT
有2 种本质上不同的染色法RGB 和RBG,使用洗牌法231 一次可得GBR 和BGR,使用洗牌法312 一次 可得BRG
和GRB。
100%数据满足 Max{Sr,Sb,Sg}<=20。
题解
Burnside引理:
对于一个置换群
等价类的个数,等于所有置换的不动点的平均数
所以,这道题目相当于有\(m+1\)个置换
求总的不动点个数
其中,置换包括不变和题目给定的\(m\)个
然后是求不动点的个数的问题
每一个置换相当于若干个循环
如果是不动点的话,
循环中的每个点的颜色应当相同
于是大力跑一个01背包就好了
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 100
#define MOD P
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int s1,s2,s3,m,P,n,ans;
int a[MAX][MAX],size[MAX];
int f[MAX][MAX][MAX];
bool vis[MAX];
int fpow(int a,int b)
{
int s=1;
while(b){if(b&1)s=1ll*s*a%P;a=1ll*a*a%P;b>>=1;}
return s;
}
int DP(int x)//求关于第x置换的不动点的个数
{
memset(size,0,sizeof(size));
memset(vis,0,sizeof(vis));
int sum=0;//拆成循环
for(int i=1;i<=n;++i)
if(!vis[i])
{
size[++sum]=1;vis[i]=true;
int p=i;
while(!vis[a[x][p]])size[sum]++,vis[p=a[x][p]]=true;
}
memset(f,0,sizeof(f));
f[0][0][0]=1;
for(int t=1;t<=sum;++t)
for(int i=s1;i>=0;--i)
for(int j=s2;j>=0;--j)
for(int k=s3;k>=0;--k)
{
if(i>=size[t])f[i][j][k]=(f[i][j][k]+f[i-size[t]][j][k])%MOD;
if(j>=size[t])f[i][j][k]=(f[i][j][k]+f[i][j-size[t]][k])%MOD;
if(k>=size[t])f[i][j][k]=(f[i][j][k]+f[i][j][k-size[t]])%MOD;
}
return f[s1][s2][s3];
}
int main()
{
s1=read();s2=read();s3=read();m=read();P=read();
n=s1+s2+s3;
for(int i=1;i<=m;++i)
for(int j=1;j<=n;++j)
a[i][j]=read();
++m;
for(int i=1;i<=n;++i)a[m][i]=i;//不动也是一种置换
for(int i=1;i<=m;++i)
ans=(ans+DP(i))%MOD;
printf("%lld\n",1ll*ans*fpow(m,P-2)%P);
return 0;
}
【BZOJ1004】Cards(组合数学,Burnside引理)的更多相关文章
- [bzoj1004][HNOI2008][Cards] (置换群+Burnside引理+动态规划)
Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红 ...
- [bzoj 1004][HNOI 2008]Cards(Burnside引理+DP)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1004 分析: 1.确定方向:肯定是组合数学问题,不是Polya就是Burnside,然后题目上 ...
- BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )
题意保证了是一个置换群. 根据burnside引理, 答案为Σc(f) / (M+1). c(f)表示置换f的不动点数, 而题目限制了颜色的数量, 所以还得满足题目, 用背包dp来计算.dp(x,i, ...
- BZOJ 1004 Cards(Burnside引理+DP)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1004 题意:三种颜色的扑克牌各有Sr,Sb,Sg张.给出m种置换.两种染色方案在某种置换 ...
- [BZOJ 1004] [HNOI2008] Cards 【Burnside引理 + DP】
题目链接:BZOJ - 1004 题目分析 首先,几个定义和定理引理: 群:G是一个集合,*是定义在这个集合上的一个运算. 如果满足以下性质,那么(G, *)是一个群. 1)封闭性,对于任意 a, b ...
- BZOJ1004 HNOI2008Cards(Burnside引理+动态规划)
直接给了一个置换群(当然要自己手动加上不洗牌的情况).考虑求不动点数量即可.对于一个置换,求出所有循环的长度,然后设f[i][x][y]为给前i个循环着色后,用了x张红色卡片.y张绿色卡片的方案数,d ...
- 【BZOJ1004】[HNOI2008]Cards Burnside引理
[BZOJ1004][HNOI2008]Cards 题意:把$n$张牌染成$a,b,c$,3种颜色.其中颜色为$a,b,c$的牌的数量分别为$sa,sb,sc$.并且给出$m$个置换,保证这$m$个置 ...
- [BZOJ1004] [HNOI2008]Cards解题报告(Burnside引理)
Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红 ...
- 【BZOJ1004】【HNOI2008】Cards 群论 置换 burnside引理 背包DP
题目描述 有\(n\)张卡牌,要求你给这些卡牌染上RGB三种颜色,\(r\)张红色,\(g\)张绿色,\(b\)张蓝色. 还有\(m\)种洗牌方法,每种洗牌方法是一种置换.保证任意多次洗牌都可用这\( ...
随机推荐
- nginx上支持.htaccess伪静态的配置实例
本文介绍下,在nginx上配置.htaccess伪静态的方法,有需要的朋友参考下吧. 在apache上.htaccess转向,只要apache编译的时候指明支持rewrite模块即可. 但是换到ngi ...
- 基于Jquery+Ajax+Json+存储过程 高效分页
在做后台开发中,都会有大量的列表展示,下面给大家给大家分享一套基于Jquery+Ajax+Json+存储过程高效分页列表,只需要传递几个参数即可.当然代码也有改进的地方,如果大家有更好的方法,愿留下宝 ...
- 地牢逃脱 (BFS)
题意:给定一个 n 行 m 列的地牢,其中 '.' 表示可以通行的位置,'X' 表示不可通行的障碍,牛牛从 (x0 , y0 ) 位置出发,遍历这个地牢,和一般的游戏所不同的是,他每一步只能按照一些指 ...
- HDU - 4135 Co-prime 容斥定理
题意:给定区间和n,求区间中与n互素的数的个数, . 思路:利用容斥定理求得先求得区间与n互素的数的个数,设表示区间中与n互素的数的个数, 那么区间中与n互素的数的个数等于.详细分析见求指定区间内与n ...
- UVA1619 栈维护递增序列
先说这题的关键性质:每一个数应该只会计算一次,它有一个最小区间[L,R],即它在这个区间内是最小的,最小区间内任何包含它的子区间都不会大于F(L,R)=(a[L]+...+a[R])*min(a[l] ...
- 在SpringBoot中配置定时任务
前言 之前在spring中使用过定时任务,使用注解的方式配置很方便,在SpringBoot中的配置基本相同,只是原来在spring中的xml文件的一些配置需要改变,在SpringBoot中也非常简单. ...
- [php] in_array 判断问题(坑)
<?php $arr = array("Linux"); if (in_array(0, $arr)) { echo "match"; } ?> 执 ...
- C语言老司机学Python (五)
今天看的是标准库概览. 操作系统接口: 用os模块实现. 针对文件和目录管理,还有个shutil模块可以用. 例句: import os os.getcwd() # 返回当前的工作目录 os.chdi ...
- 遍历对象属性(for in、Object.keys、Object.getOwnProperty)
js中几种遍历对象的方法,包括for in.Object.keys.Object.getOwnProperty,它们在使用场景方面各有不同. for in 主要用于遍历对象的可枚举属性,包括自有属性. ...
- arm_linux_device_mem内存映射
/dev/mem: 物理内存的全镜像.可以用来访问物理内存. /dev/kmem: kernel看到的虚拟内存的全镜像.可以用来访问kernel的内容. /dev/mem 用来访问物理IO设备比如X ...