bzoj 1004 Cards
1004: [HNOI2008]Cards
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定理,即在集合\(X\)上的群\(G\),对于\(g \in G\),令\(X^g\)为在\(g\)作用下的不动元素,有\(|X/G|={1 \over {|G|}} \sum_{g \in G}|X^g|\)。
在此题中就可以得出\(Ans = \sum Cal(change_i) * |G|^{-1}\),其中\(Cal\)计算每种置换的方案数。
Ps:
- 除去题中给出的置换,还有一个不变的置换。
- 关于群论的知识,可以上Wiki。这里有一篇博客是有关群论的简介
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 65, M = 105;
int n, m, p, sr, sb, sg;
int dp[N][N][N], cha[M][N], d[N];
bool vis[N];
#define Inc(a,b) ((a) = ((a) + (b))%p)
int Cal(const int &x) {
memset(dp, 0, sizeof dp);
memset(vis, 0, sizeof vis);
int Sum = 0, t;
for (int i = 1; i <= n; ++i)
if (!vis[i]) {
d[++Sum] = 1; vis[t = i] = true;
while (!vis[cha[x][t]]) {
++d[Sum]; t = cha[x][t];
vis[t] = true;
}
}
dp[0][0][0] = 1;
for (t = 1; t <= Sum; ++t)
for (int i = sr; ~i; --i)
for (int j = sb; ~j; --j)
for (int k = sg; ~k; --k) {
if (i >= d[t]) Inc(dp[i][j][k], dp[i-d[t]][j][k]);
if (j >= d[t]) Inc(dp[i][j][k], dp[i][j-d[t]][k]);
if (k >= d[t]) Inc(dp[i][j][k], dp[i][j][k-d[t]]);
}
//printf("%d\n", dp[sr][sb][sg]);
return dp[sr][sb][sg];
}
long long Mod_Pow(long long b, int c) {
long long ans = 1LL;
while (c) {
if (c&1) ans = ans * b % p;
b = b * b % p;
c >>= 1;
}
return ans;
}
int main() {
scanf("%d%d%d%d%d", &sr, &sb, &sg, &m, &p);
n = sr + sb + sg;
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
scanf("%d", cha[i] + j);
++m;
long long ans = 0;
for (int i = 1; i <= n; ++i) cha[m][i] = i;
for (int i = 1; i <= m; ++i) Inc(ans, Cal(i));
//printf("%d\n", ans);
ans = ans * Mod_Pow(m, p - 2) % p;
printf("%lld\n", ans);
return 0;
}
bzoj 1004 Cards的更多相关文章
- BZOJ 1004 Cards(Burnside引理+DP)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1004 题意:三种颜色的扑克牌各有Sr,Sb,Sg张.给出m种置换.两种染色方案在某种置换 ...
- bzoj 1004 Cards 组合计数
这道题考察的是组合计数(用Burnside,当然也可以认为是Polya的变形,毕竟Polya是Burnside推导出来的). 这一类问题的本质是计算置换群(A,P)中不动点个数!(所谓不动点,是一个二 ...
- bzoj 1004 Cards & poj 2409 Let it Bead —— 置换群
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1004 关于置换群:https://www.cnblogs.com/nietzsche-oie ...
- BZOJ 1004 Cards(Burnside引理+DP)
因为有着色数的限制,故使用Burnside引理. 添加一个元置换(1,2,,,n)形成m+1种置换,对于每个置换求出循环节的个数, 每个循环节的长度. 则ans=sigma(f(i))/(m+1) % ...
- [BZOJ 1004] [HNOI2008] Cards 【Burnside引理 + DP】
题目链接:BZOJ - 1004 题目分析 首先,几个定义和定理引理: 群:G是一个集合,*是定义在这个集合上的一个运算. 如果满足以下性质,那么(G, *)是一个群. 1)封闭性,对于任意 a, b ...
- bzoj 1004 [HNOI2008]Cards && poj 2409 Let it Bead ——置换群
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1004 http://poj.org/problem?id=2409 学习材料:https:/ ...
- bzoj 1004 1004: [HNOI2008]Cards burnside定理
1004: [HNOI2008]Cards Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1668 Solved: 978[Submit][Stat ...
- BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )
题意保证了是一个置换群. 根据burnside引理, 答案为Σc(f) / (M+1). c(f)表示置换f的不动点数, 而题目限制了颜色的数量, 所以还得满足题目, 用背包dp来计算.dp(x,i, ...
- 【BZOJ 1004】 1004: [HNOI2008]Cards (置换、burnside引理)
1004: [HNOI2008]Cards Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很 ...
随机推荐
- 可扩展的事件复用技术:epoll和kqueue
通常来说我喜欢Linux更甚于BSD系统,但是我真的想在Linux上拥有BSD的kqueue功能. 什么是事件复用技术 假设你有一个简单的web服务器,并且那里已经打开了两个socket连接.当服务器 ...
- hive 内部表和外部表的区别和理解
1. 内部表 create table test (name string , age string) location '/input/table_data'; 注:hive默认创建的是内部表 此时 ...
- js控制复选框checkbox 只能单选
我们在页面经常会用到单选框,来提供单值选在字段,但是有一个问题就是:一旦选择了就不能去除(即--只要选择了就不能再以空值提交了). 所以为了解决这个问题,用复选框限制单选是一个不错的选择 <sc ...
- date命令总结
date命令是显示或设置系统时间与日期 date(选项)(参数) -d<字符串>:显示字符串所指的日期与时间.字符串前后必须加上双引号: -s<字符串>:根据字符串来设置日期与 ...
- POJ1236Network of Schools[强连通分量|缩点]
Network of Schools Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 16571 Accepted: 65 ...
- Maven配置详见
CSDN 2016博客之星评选结果公布 [系列直播]零基础学习微信小程序! "我的2016"主题征文活动 博客的神秘功能 maven 配置详解 标签: mave ...
- [转载]彻底弄清struct和typedef struct
struct和typedef struct 分三块来讲述: 1 首先://注意在C和C++里不同 在C中定义一个结构体类型要用typedef: typedef struct Student { int ...
- [luogu2964][USACO09NOV][硬币的游戏A Coin Game] (博弈+动态规划)
题目描述 Farmer John's cows like to play coin games so FJ has invented with a new two-player coin game c ...
- LeetCode "419. Battleships in a Board"
The follow-up question is fun: "Could you do it in one-pass, using only O(1) extra memory and w ...
- TCP connect的错误返回值
如果是TCP套接字,调用connect函数将激发TCP三次握手过程,而且仅在连接建立成功或出错时返回,其中错误返回可能有下面几种情况: (1)若TCP客户没有收到SYN分节的响应,则返回ETIMEDO ...