【BZOJ 1004】【HNOI 2008】Cards
2024-08-26 00:04:17
http://www.lydsy.com/JudgeOnline/problem.php?id=1004
注意数据给出的m是一个没有单位元的置换群!
用Burnside引理,然后对每个置换群dp一下就可以了。
#include<cstdio>
#include<bitset>
#include<cstring>
#include<algorithm>
using namespace std;
int a[63], Sr, Sb, Sg, m, p, n, ans = 0;
int ipow(int w, int b) {
int ret = 1;
while (b) {
if (b & 1) ret = ret * w % p;
w = w * w % p;
b >>= 1;
}
return ret;
}
int f[63][63][63][63], w[63], tot;
bitset <64> vis;
int dp() {
vis.reset(); tot = 0;
for (int i = 1; i <= n; ++i)
if (!vis[i]) {
vis[i] = 1;
w[++tot] = 1;
int tmp = a[i];
while (!vis[tmp]) {
vis[tmp] = 1;
++w[tot];
tmp = a[tmp];
}
}
for (int i = 1; i <= tot; ++i)
for (int R = 0; R <= Sr; ++R)
for (int B = 0; B <= Sb; ++B)
for (int G = 0; G <= Sg; ++G) {
f[i][R][B][G] = 0;
if (R >= w[i]) (f[i][R][B][G] += f[i - 1][R - w[i]][B][G]) %= p;
if (B >= w[i]) (f[i][R][B][G] += f[i - 1][R][B - w[i]][G]) %= p;
if (G >= w[i]) (f[i][R][B][G] += f[i - 1][R][B][G - w[i]]) %= p;
}
return f[tot][Sr][Sb][Sg];
}
int main() {
scanf("%d%d%d%d%d", &Sr, &Sb, &Sg, &m, &p);
n = Sr + Sb + Sg; f[0][0][0][0] = 1;
for (int j = 1; j <= n; ++j) a[j] = j;
(ans += dp()) %= p;
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) scanf("%d", a + j);
(ans += dp()) %= p;
}
printf("%d\n", ans * ipow(m + 1, p - 2) % p);
return 0;
}
最新文章
- When I see you again(加密原理介绍,代码实现DES、AES、RSA、Base64、MD5)
- Ember入门指南——教程目录
- Linux aclocal
- Android基础知识总结
- (译)详解javascript立即执行函数表达式(IIFE)
- asp.net mvc 利用过滤器进行网站Meta设置
- Entity Framework Fluent API
- Java for LeetCode 072 Edit Distance【HARD】
- Android 内核初识(1)下载源码需求与教程
- swift material
- Weka算法介绍
- PHP设计模式一:工厂方法设计模式
- JavaUtil_06_DES加解密工具
- ELK简单安装
- RNA-seq基本流程
- VS2013开发上位机并调用MSCcommm控件的方式
- Shell脚本编程基础笔记二
- CentOS下安装Hbase
- PHP批量添加数据
- 【转】c#.net各种应用程序中获取文件路径的方法