题目链接:BZOJ - 1004

题目分析

首先,几个定义和定理引理:

群:G是一个集合,*是定义在这个集合上的一个运算。

如果满足以下性质,那么(G, *)是一个群。

1)封闭性,对于任意 a, b 属于 G, a * b 属于 G

2)结合律, a * b * c = a * (b * c)

3)单位元,在 G 中存在一个单位元 e ,使得对于 G 中任意的 a , a * e = e * a = a

4)逆元, 对于 G 中任意的 a ,在 G 中存在 b , 使得 a * b = e , 其中 b 叫做 a 的逆元

比如在模一个数意义下的整数加法就是一个群。

满足交换律的群是交换群,又叫阿贝尔群。

置换:可以用 (a1 -> b1, a2 -> b2, ... , an -> bn) 表示一个置换,其中 a1, ... , an 和 b1, ..., bn 都是1 到 n 的一个排列;

如果一些置换和它们的叠加运算构成一个群,就把它们叫做一个置换群。

在置换群中的 Burnside 引理:如果按照一定要求,要对1到n 的位置染色,那么本质不同的染色方案数为置换群中每个置换的不动染色方案数的平均数。

来解释以下,本质不同的染色方案是指,两个染色方案不能通过置换群中的任意置换变换使其相同,那么它们就是本质不同的。

某个置换的不动染色方案数是指,用这个置换变换之后没有发生变化的染色方案。

那么我们就是要求出每个置换的不动染色方案数。

Polya定理告诉我们,如果是用k种颜色染色,那么对于置换 P 来说,它的不动染色方案数为 k^(L(P)), 其中L(P)为置换P的循环节数。

这个很好理解,因为每个循环节如果要使置换之后不改变的话,应该使这个循环节中都染同一种颜色。

但是,这道题的染色要求是给定了3种颜色的数量,就不能用 k^(L(P)) 来求了。

我们使用一种3维DP,还是先搜索一遍求出这个置换的所有循环节的大小。然后把每个循环节看作一个物品,染一种颜色。

用 f[i][j][k] 表示染了前 i 件物品,第1种颜色用了 j 个, 第2种颜色用了 k 次的染色方案数。

这道题还需要注意的一点是,需要加上一个不做任何改变的置换作为单位元才能成为一个置换群。

这个单位元的不动染色方案数就是所有的染色方案数,直接用多重集排列就好了, n! / (a! b! c!)。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm> using namespace std; const int MaxN = 60; int Na, Nb, Nc, n, m, Mod, Ans, Top;
int A[MaxN], V[MaxN], Sum[MaxN], f[MaxN][MaxN][MaxN]; bool Used[MaxN]; inline int Pow(int a, int b)
{
int ret = 1, f = a;
while (b)
{
if (b & 1)
{
ret *= f;
ret %= Mod;
}
b >>= 1;
f *= f;
f %= Mod;
}
return ret;
} inline int NY(int x) {return Pow(x, Mod - 2);} void DFS(int x, int Num)
{
if (Used[x])
{
V[++Top] = Num;
return;
}
Used[x] = true;
DFS(A[x], Num + 1);
} inline int Fac(int x)
{
int ret = 1;
for (int i = 1; i <= x; ++i)
{
ret *= i;
ret %= Mod;
}
return ret;
} int main()
{
scanf("%d%d%d%d%d", &Na, &Nb, &Nc, &m, &Mod);
n = Na + Nb + Nc;
Ans = Fac(n) * NY(Fac(Na)) % Mod * NY(Fac(Nb)) % Mod * NY(Fac(Nc)) % Mod;
for (int i = 1; i <= m; ++i)
{
for (int j = 1; j <= n; ++j)
{
scanf("%d", &A[j]);
Used[j] = false;
}
Top = 0;
for (int j = 1; j <= n; ++j)
if (!Used[j]) DFS(j, 0);
Sum[0] = 0;
for (int j = 1; j <= Top; ++j)
Sum[j] = Sum[j - 1] + V[j];
f[0][0][0] = 1;
for (int j = 1; j <= Top; ++j)
{
for (int p = 0; p <= Na; ++p)
{
for (int q = 0; q <= Nb; ++q)
{
f[j][p][q] = 0;
if (p >= V[j])
{
f[j][p][q] += f[j - 1][p - V[j]][q];
f[j][p][q] %= Mod;
}
if (q >= V[j])
{
f[j][p][q] += f[j - 1][p][q - V[j]];
f[j][p][q] %= Mod;
}
if ((Sum[j] - p - q) >= V[j])
{
f[j][p][q] += f[j - 1][p][q];
f[j][p][q] %= Mod;
}
}
}
}
Ans += f[Top][Na][Nb];
Ans %= Mod;
}
Ans *= NY(m + 1);
Ans %= Mod;
printf("%d\n", Ans);
return 0;
}

  

[BZOJ 1004] [HNOI2008] Cards 【Burnside引理 + DP】的更多相关文章

  1. BZOJ 1004 HNOI2008 Cards Burnside引理

    标题效果:特定n张卡m换人,编号寻求等价类 数据保证这m换人加上置换群置换后本身构成 BZOJ坑爹0.0 条件不那么重要出来尼玛怎么做 Burnside引理--昨晚为了做这题硬啃了一晚上白书0.0 都 ...

  2. bzoj1004: [HNOI2008]Cards(burnside引理+DP)

    题目大意:3种颜色,每种染si个,有m个置换,求所有本质不同的染色方案数. 置换群的burnside引理,还有个Pólya过几天再看看... burnside引理:有m个置换k种颜色,所有本质不同的染 ...

  3. BZOJ 1004: [HNOI2008]Cards [Polya 生成函数DP]

    传送门 题意:三种颜色,规定使用每种颜色次数$r,g,b$,给出一个置换群,求多少种不等价着色 $m \le 60,\ r,g,b \le 20$ 咦,规定次数? <组合数学>上不是有生成 ...

  4. BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )

    题意保证了是一个置换群. 根据burnside引理, 答案为Σc(f) / (M+1). c(f)表示置换f的不动点数, 而题目限制了颜色的数量, 所以还得满足题目, 用背包dp来计算.dp(x,i, ...

  5. bzoj 1004 1004: [HNOI2008]Cards burnside定理

    1004: [HNOI2008]Cards Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1668  Solved: 978[Submit][Stat ...

  6. bzoj1004 [HNOI2008]Cards Burnside 引理+背包

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1004 题解 直接 Burnside 引理就可以了. 要计算不动点的个数,那么对于一个长度为 \ ...

  7. BZOJ 1004 Cards(Burnside引理+DP)

    因为有着色数的限制,故使用Burnside引理. 添加一个元置换(1,2,,,n)形成m+1种置换,对于每个置换求出循环节的个数, 每个循环节的长度. 则ans=sigma(f(i))/(m+1) % ...

  8. 【bzoj1004】[HNOI2008]Cards Burnside引理+背包dp

    题目描述 用三种颜色染一个长度为 $n=Sr+Sb+Sg$ 序列,要求三种颜色分别有 $Sr,Sb,Sg$ 个.给出 $m$ 个置换,保证这 $m$ 个置换和置换 ${1,2,3,...,n\choo ...

  9. BZOJ1004: [HNOI2008]Cards(Burnside引理 背包dp)

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4255  Solved: 2582[Submit][Status][Discuss] Descript ...

随机推荐

  1. Pilin —— 一个基于Xmpp openfire smack的即时聊天工具

    https://github.com/whfcomm/Pilin

  2. Windows环境下tomcat配置日志输出

    在Linux系统中,可以通过tail  -f  catalina.out 来跟踪Tomcat 和相关应用运行的情况. 在windows下,catalina日志与Linux记录的内容有很大区别,大多信息 ...

  3. hdu1864 最大报销额(01背包)

    转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1864 Problem ...

  4. QuaZip实现多文件打包

    项目需求: 在Goldenfarm客户端中当用户选择了本地场景文件,并进行本地场景文件分析后会产生分析结果,分析结果主要包括:贴图纹理.可渲染层等,其中贴图纹理指出了在场景文件中使用到的贴图或其它文件 ...

  5. Visual Studio 调试技巧 (三) -- 调试第三方组件代码

    上次我们提到,没有源代码而且没有调试符号,我们也可以 Debug.有人可能会问,我什么时候需要在这种情况下调试吗?! 是的.比方说,我们用了某些第三方的组件,这些组件里面难免也会有 Bug.就算是微软 ...

  6. Bash中的数组

    变量:$VAR或者${VAR} 数组:${VAR[$i]} 打印整个数组:echo ${VAR[@]} 统计数组元素个数:echo ${#VAR[@]} 从文件读入数组(按行读入):VAR=(`cat ...

  7. Linux下Tomcat安装、配置

    /etc/profile./etc/profile.d和.bash_profile区别 /etc/profile和/etc/profile.d区别 .bash_profile 是存放用户的全局变量 / ...

  8. 【Oracle】INSERT INTO SELECT语句和SELECT INTO FROM语句的区别

    >>>>>>>>>>>>>>>>>>>>>>>>> ...

  9. 解决 TortoiseGit 诡异的 Bad file number 问题

    http://blog.csdn.net/renfufei/article/details/41648061 问题描述 昨天,以及今天(2014-11-29),使用 TortoiseGit 时碰到了一 ...

  10. AsyncTask理解- Day36or37

    AsyncTask理解- Day36or37 mobile 5.0 1.手机归属地查询 AtoolsActivity Assets目录特点 该文件是原生文件,不会对里面的文件进行编码 该文件只支持读取 ...