【题意分析】

  给N个元素染色,可以在定置换群的作用下互相转化的染色方案算相同的,问本质不同的染色方案数。

【解题思路】

  引理:Burnside定理

设集合S=[1,n]∩N,记等价类数为L,给定S上的置换群G。

Zk (k不动置换类):若k是S中某个元素,G中使k保持不变的置换的全体,记以Zk,叫做G中使k保持不动的置换类,简称k不动置换类。

C(π)(置换n的不动点全集):对于一个置换π∈G,及a∈X,若π(a)=a,则称a为π的不动点。π的不动点的全体记为C(π)。

有定理:L=1/|G|*∑|Zk|(k∈S)=1/|G|*Σ|C(n)|(n∈G)。

  所以,我们只要分别计算G中每个置换的不动点数,就可以计算出等价类数。外层复杂度O(m)。

  考虑染色,对于每个置换,在同一个置换环中的元素必定染成同色,才能保证集合range(n)经过置换后染色方案不变,所以可以用三维背包来计算方案数。内层复杂度O(SrSgSb+n)。

  总复杂度O(n^2+nSrSgSb)。

【参考代码】

 #include <cmath>
#include <cstdio>
#define REP(I,start,end) for(int I=(start);I<=(end);I++)
#define PER(I,start,end) for(int I=(start);I>=(end);I--)
#define REPs(I,start,end,step) for(int I=(start);I<=(end);I+=(step))
#define PERs(I,start,end,step) for(int I=(start);I>=(end);I-=(step))
using namespace std;
typedef unsigned short US;
typedef unsigned long UL;
typedef long long LL;
typedef unsigned long long ULL;
inline int getint()
{
char ch=getchar();
while((ch<''||ch>'')&&ch!='-')
ch=getchar();
int result=0;
bool impositive=ch=='-';
if(impositive)
ch=getchar();
while(ch>=''&&ch<='')
{
result=(result<<3)+(result<<1)+ch-'';
ch=getchar();
}
return impositive?-result:result;
}
inline int putint(int n)
{
int result=1;
char* sav=new char[20];
bool impositive=n<0;
if(impositive)
{
putchar('-');
n=-n;
}
sav[0]=n%10+'';
while(n/=10)
sav[result++]=n%10+'';
PER(i,result-1,0)
putchar(sav[i]);
delete []sav;
return result+impositive;
}
inline LL getLL()
{
char ch=getchar();
while((ch<''||ch>'')&&ch!='-')
ch=getchar();
LL result=0ll;
bool impositive=ch=='-';
if(impositive)
ch=getchar();
while(ch>=''&&ch<='')
{
result=(result<<3)+(result<<1)+ch-'';
ch=getchar();
}
return impositive?-result:result;
}
inline int putLL(LL n)
{
int result=1;
char* sav=new char[20];
bool impositive=n<0;
if(impositive)
{
putchar('-');
n=-n;
}
sav[0]=n%10+'';
while(n/=10)
sav[result++]=n%10+'';
PER(i,result-1,0)
putchar(sav[i]);
delete []sav;
return result+impositive;
}
template<typename integer> inline int read_int(integer &n)
{
char ch=getchar();
while((ch<''||ch>'')&&ch!='-')
ch=getchar();
int result=n=integer(0);
bool impositive=ch=='-';
if(impositive)
ch=getchar();
while(ch>=''&&ch<='')
{
n=(n<<3)+(n<<1)+integer(ch-'');
result++;
ch=getchar();
}
if(impositive)
{
n=-n;
result++;
}
return result;
}
template<typename integer> inline int write_int(integer n)
{
int result=1;
char* sav=new char[20];
bool impositive=n<0;
if(impositive)
{
putchar('-');
n=-n;
}
sav[0]=n%10+'';
while(n/=10)
sav[result++]=n%10+'';
PER(i,result-1,0)
putchar(sav[i]);
delete []sav;
return result+impositive;
}
template<typename integer> inline integer sqr(integer n)
{
return n*n;
}
template<typename base_type,typename exp_type> inline base_type PowerMod(base_type Base,exp_type Exp,base_type Mod)
{
bool* sav=new bool[int(log(Exp)/log(2))+1];
int tot=0;
base_type result=base_type(1),baser=Base%Mod;
exp_type tmp=Exp;
while(tmp)
{
sav[tot++]=tmp&1;
tmp>>=1;
}
while(tot)
{
result=sqr(result)%Mod;
if(sav[--tot])
result=result*baser%Mod;
}
delete []sav;
return result;
}
//====================================Header Template===================================
#include <cstring>
bool used[100];
int sr,sb,sg,n,p,trans[100],cnt[100],f[30][30][30];
inline int mod_reverse(int _n,int _p)
{
return PowerMod(_n,_p-2,_p);
}
inline int DP()
{
memset(f,0,sizeof(f));
memset(used,0,sizeof(used));
int group=0;
REP(i,1,n)
if(!used[i])
{
used[i]=true;
int j=trans[i],tot=1;
while(!used[j])
{
used[j]=true;
tot++;
j=trans[j];
}
cnt[++group]=tot;
}
f[0][0][0]=1;
REP(g,1,group)
PER(i,sr,0)
PER(j,sb,0)
PER(k,sg,0)
{
if(i>=cnt[g])
(f[i][j][k]+=f[i-cnt[g]][j][k])%=p;
if(j>=cnt[g])
(f[i][j][k]+=f[i][j-cnt[g]][k])%=p;
if(k>=cnt[g])
(f[i][j][k]+=f[i][j][k-cnt[g]])%=p;
}
return f[sr][sb][sg];
}
int main()
{
sr=getint();
sb=getint();
sg=getint();
int m=getint();
p=getint();
n=sr+sb+sg;
int ans=0;
REP(i,1,m)
{
REP(j,1,n)
trans[j]=getint();
(ans+=DP())%=p;
}
REP(i,1,n)
trans[i]=i;
(ans+=DP())%=p;
putint(ans*mod_reverse(m+1,p)%p);
return 0;
}

bzoj1004题解的更多相关文章

  1. BZOJ1004 [HNOI2008]Cards 【burnside定理 + 01背包】

    题目链接 BZOJ1004 题解 burnside定理 在\(m\)个置换下本质不同的染色方案数,等于每种置换下不变的方案数的平均数 记\(L\)为本质不同的染色方案数,\(m\)为置换数,\(f(i ...

  2. [题解]BZOJ1004 序列函数

    原题找不到了,应该是usaco之类的题目吧.给一个可以交题的链接:http://www.cqoi.net:2012/problem.php?id=1004 思路:将素数一个一个往里乘,保证扫描的顺序是 ...

  3. 【bzoj1004】 HNOI2008—Cards

    http://www.lydsy.com/JudgeOnline/problem.php?id=1004 (题目链接) 题意 n张卡片,染成3种颜色,每种颜色只能染固定张数.给出一些洗牌方案,问染色方 ...

  4. 【BZOJ1004】Cards(组合数学,Burnside引理)

    [BZOJ1004]Cards(组合数学,Burnside引理) 题面 Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Su ...

  5. 【BZOJ1004】[HNOI2008]Cards Burnside引理

    [BZOJ1004][HNOI2008]Cards 题意:把$n$张牌染成$a,b,c$,3种颜色.其中颜色为$a,b,c$的牌的数量分别为$sa,sb,sc$.并且给出$m$个置换,保证这$m$个置 ...

  6. bzoj1004 [HNOI2008]Cards 置换群+背包

    [bzoj1004][HNOI2008]Cards 2014年5月26日5,3502 Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿 ...

  7. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  8. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  9. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

随机推荐

  1. 关键字this super final static

    this关键字 1.this代表通过当前类实例化成的对象. 2.通过this来获取当前类的属性和方法 3.通过this和区分成员变量和局部变量 4.通过this(参数),调用当前类的构造方法 注意:通 ...

  2. 深入理解Magento - 第五章 Magento资源配置

    对于任何一个更新频繁的项目来说,保持开发环境和生产环境的数据库同步是件很头疼的事情.Magento提供了一套系统,用版本化的资源迁移脚本来解决这个问题. 上一章,我们为 Helloworld Blog ...

  3. Delphi获取指定文件的版本号

    获取指定文件的版本号 方式一: function GetFileVersion(FileName: string): string; type PVerInfo = ^TVS_FIXEDFILEINF ...

  4. bzoj 2631

    lct 基础(' '   ) 就当个纪念吧(' '    )  毕竟写了4h, cut 部分一直naive 总是想找谁是儿子,然后最后发现直接提根就好了啊(' '   ) #include <i ...

  5. CSP-S2019退役记

    分两次写完思路不是很清晰. 作为一名强迫症患者我选择以后再更新一些细节…… upd 真·退役,D1T1为什么都是95分算法他们AC了我挂成了70分555555555555 普及-的题目A不掉我死了55 ...

  6. 【LeetCode 26】删除排序数组中的重复项

    题目链接 [题解] 沙比提 [代码] class Solution { public: int removeDuplicates(vector<int>& nums) { if ( ...

  7. linux基础知识汇总(四)--ps grep命令

    转:http://www.cnblogs.com/allen8807/archive/2010/11/10/1873843.html http://www.cnblogs.com/end/archiv ...

  8. windows 驱动开发 DDK与WDK WDM的区别

    1.首先,先从基础的东西说起,开发WINDOWS下的驱动程序,需要一个专门的开发包,如:开发JAVA程序,我们可能需要一个JDK,开发WINDOWS应用程序,我们需要WINDOWS的SDK,现在开发W ...

  9. CentOS6.8搭建LNMP环境

    selinux可能会致使编译安装失败,我们先禁用它.永久禁用,需要重启生效 sed -i ‘s/SELINUX=enforcing/SELINUX=disabled/g’ /etc/selinux/c ...

  10. ajax - getJSON() 方法

    $("body").on("click",".layui-input-inline:eq(3)",function(){ $(this).f ...