【bzoj1004】[HNOI2008]Cards

1004: [HNOI2008]Cards

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2928  Solved: 1754
[Submit][Status][Discuss]

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定理,ans就是每种置换下不动点的数目的和除以m

然而这道题关于颜色有限制,那么我们可以用f[i][j][k]表示用了i种颜色1,j种颜色2,k种颜色3的相同的方案数,b[h]表示循环节的长度,那么可以得到f[i][j][k]=f[i-d[h]][j][k]+f[i][j-d[h]][k]+f[i][j][k-d[h]]

求出ans之后,由于计算出的ans是取模后的结果,然后要除以m,然后。。。乘法逆元解决。

最后别忘了,除了题上给出的置换外,还有一个固定的置换,就是自身的置换。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<ctime>
 7 #include<algorithm>
 8 using namespace std;
 9 int sr,sb,sg,m,n,mod,ans,a[61][61],b[61],f[61][61][61],d[61];
10 inline int read()
11 {
12     int x=0;char ch=getchar();
13     while(ch<‘0‘||ch>‘9‘)ch=getchar();
14     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
15     return x;
16 }
17 int dp(int x)
18 {
19     for(int i=1;i<=n;i++)  b[i]=0;
20     int sum=0,p=0;
21     for(int i=1;i<=n;i++)
22         if(!b[i])
23         {
24             p=i;  b[p]=1;  d[++sum]=1;
25             while(!b[a[x][p]])
26             {
27                 b[a[x][p]]=1;
28                 d[sum]++;
29                 p=a[x][p];
30             }
31         }
32     for(int i=sr;i>=0;i--)
33         for(int j=sb;j>=0;j--)
34             for(int k=sg;k>=0;k--)
35                 f[i][j][k]=0;
36     f[0][0][0]=1;
37     for(int h=1;h<=sum;h++)
38         for(int i=sr;i>=0;i--)
39             for(int j=sb;j>=0;j--)
40                 for(int k=sg;k>=0;k--)
41                 {
42                     if(i>=d[h])  f[i][j][k]=(f[i][j][k]+f[i-d[h]][j][k])%mod;
43                     if(j>=d[h])  f[i][j][k]=(f[i][j][k]+f[i][j-d[h]][k])%mod;
44                     if(k>=d[h])  f[i][j][k]=(f[i][j][k]+f[i][j][k-d[h]])%mod;
45                 }
46     return f[sr][sb][sg];
47 }
48 void exgcd(int a,int b,int &x,int &y)
49 {
50     if(b==0)  {x=1;  y=0;  return;}
51     exgcd(b,a%b,x,y);
52     int t=x;  x=y;  y=t-a/b*y;
53 }
54 int main()
55 {
56     sr=read();  sb=read();  sg=read();  m=read();  mod=read();
57     n=sr+sb+sg;
58     for(int i=1;i<=m;i++)
59         for(int j=1;j<=n;j++)
60             a[i][j]=read();
61     m++;
62     for(int i=1;i<=n;i++)  a[m][i]=i;
63     for(int i=1;i<=m;i++)  ans=(ans+dp(i))%mod;
64     int x,y;
65     exgcd(m,mod,x,y);
66     while(x<0)  x+=mod;
67     printf("%d\n",ans*x%mod);
68     return 0;
69 }

时间: 2024-10-26 05:57:28

【bzoj1004】[HNOI2008]Cards的相关文章

【BZOJ1004】[HNOI2008]Cards Burnside引理

[BZOJ1004][HNOI2008]Cards 题意:把$n$张牌染成$a,b,c$,3种颜色.其中颜色为$a,b,c$的牌的数量分别为$sa,sb,sc$.并且给出$m$个置换,保证这$m$个置换加上本身的置换能构成一个置换群,两种染色方案被认为是相同的当且仅当一种方案可以通过某个置换变成另一种.求不同的染色方案数.答案对$P$取模. $sa,sb,sc\le 20,m\le 60$ 题解:这里对每种颜色都有一个限制,怎么办呢? 回顾从Burnside引理到Pólya定理的推导过程. 如果

【bzoj1004】 HNOI2008—Cards

http://www.lydsy.com/JudgeOnline/problem.php?id=1004 (题目链接) 题意 n张卡片,染成3种颜色,每种颜色只能染固定张数.给出一些洗牌方案,问染色方案数. Solution Burnside引理. 左转题解:LCF 代码 // bzoj1004 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #includ

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

题目描述 用三种颜色染一个长度为 $n=Sr+Sb+Sg$ 序列,要求三种颜色分别有 $Sr,Sb,Sg$ 个.给出 $m$ 个置换,保证这 $m$ 个置换和置换 ${1,2,3,...,n\choose 1,2,3,...,n}$ 构成一个置换群,求置换后不同构的序列个数模 $p$ . $0\le Sr,Sb,Sg\le 20,0\le m\le 60,m+1\le p\le 100$ ,$p$ 是质数. 输入 第一行输入 5 个整数:Sr,Sb,Sg,m,p(m<=60,m+1<p<

【BZOJ1007】[HNOI2008]水平可见直线 半平面交

[BZOJ1007][HNOI2008]水平可见直线 Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.例如,对于直线:L1:y=x; L2:y=-x; L3:y=0则L1和L2是可见的,L3是被覆盖的.给出n条直线,表示成y=Ax+B的形式(|A|,|B|<=500000),且n条直线两两不重合.求出所有可见的直线. Input 第一行为N(0 < N < 50000

【BZOJ1009】[HNOI2008]GT考试 next数组+矩阵乘法

[BZOJ1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为0 Input 第一行输入N,M,K.接下来一行输入M位的数. N<=10^9,M<=20,K<=1000 Output 阿申想知

【bzoj1006】[HNOI2008]神奇的国度

1006: [HNOI2008]神奇的国度 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3114  Solved: 1401[Submit][Status][Discuss] Description K国是一个热衷三角形的国度,连人的交往也只喜欢三角原则.他们认为三角关系:即AB相互认识,BC相互认识,CA相互认识,是简洁高效的.为了巩固三角关系,K国禁止四边关系,五边关系等等的存在.所谓N边关系,是指N个人 A1A2...An之间仅存在N对认

【BZOJ】1003 Cards

[解析]Burnside引理+背包dp+乘法逆元 [Analysis] 这道题卡了好久,就是没想懂置换跟着色是不一样的. 根据burnside引理,在一个置换群作用下不等价类的个数为每个置换作用下不动点个数的平均数. 在这道题中: 置换的对象 -- 每个状态,标号为1-N(这里的N不是题目的N,而是状态的个数). 不动点 -- 前后染色状态完全相同的状态的个数. 所以就是求经过变换后前后状态完全相同的个数. [Sum] Burnside引理几个注意的地方 [1]什么是Burnside引理? [2

【SPFA】POJ1511-Invitation Cards

2题目大意] 给出一张有向图,以1位源点,求“从源点出发到各点的距离”和“与各点返回源点的距离和”相加得到的和. [思路] 毫无疑问是最短路径,但是这数据量就算是SPFA也绝壁会超时啊,抱着必死的心态写了submitt,居然AC..才意识到Time Limit: 8000MS. 大体的实现方法就用SPFA先计算出单源最短路径,接着再把每一条边中起始点和终止点进行对话,把各点返回源点的最短路径转换为单源最短路径,重复操作. SPFA的思路大致如下:先将源点加入队列.对于队列中的队首,对于以它为起始

【bzoj1011】[HNOI2008]遥远的行星

#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<cmath> #include<queue> using namespace std; typedef long double LD; #define N 100010 long double a; int n,T=50;