BZOJ1004: [HNOI2008]Cards

终于是把这题过了。

首先,一个赤裸裸的置换在那,显然不是Burnside就是Pólya。

这题由于有三种颜色且颜色数是有限的,Pólya是没法用了,上Burnside。

Burnside是说,真正意义上不变的染色方案数=Σ(每种置换下不变的染色方案数)/(置换总数)

求出每种置换下不变的染色方案数便显得很重要,这里便需要特殊到这道题了。

对于每一种置换,我们求出其循环节(超像Pólya!),显然的,每个循环节必须染同样的颜色。

接下来,就能够通过一个DP将整个分子求出。

而分母,由于是除法,所以需要用到乘法逆元,又因为这里保证p为素数,所以可以直接用快速幂来求逆元。

调试小结:

  1.DP时不能从小往大DP(或者写4维的),会重复计算。

 1 /**************************************************************
 2     Problem: 1004
 3     User: zhuohan123
 4     Language: C++
 5     Result: Accepted
 6     Time:152 ms
 7     Memory:1380 kb
 8 ****************************************************************/
 9  
10 #include <iostream>
11 #include <cstdio>
12 #include <cstring>
13 using namespace std;
14 int sr,sg,sb,m,p,n;
15 inline void add(int &a,int b){a=(a+b)%p;}
16 int z[100],s[100],snum;
17 bool ha[100];
18 int f[30][30][30];
19 int calc()
20 {
21     memset(f,0,sizeof f);
22     memset(ha,0,sizeof ha);
23     memset(s,0,sizeof s);
24     snum=0;
25     for(int i=1;i<=n;i++)
26         if(!ha[i])
27         {
28             snum++;
29             for(int j=i;!ha[j];j=z[j])ha[j]=true,s[snum]++;
30         }
31     f[0][0][0]=1;
32     for(int i=1;i<=snum;i++)
33         for(int r=sr;r>=0;r--)
34         for(int g=sg;g>=0;g--)
35         for(int b=sb;b>=0;b--)
36         {
37             if(r>=s[i])add(f[r][g][b],f[r-s[i]][g][b]);
38             if(g>=s[i])add(f[r][g][b],f[r][g-s[i]][b]);
39             if(b>=s[i])add(f[r][g][b],f[r][g][b-s[i]]);
40         }
41      
42     return f[sr][sg][sb];
43 }
44 inline int sqr(int a){return a*a;}
45 int exp(int a,int b,int p)
46 {
47     return b?sqr(exp(a,b/2,p))%p*((b&1)?a:1)%p:1;
48 }
49 int main(int argc, char *argv[])
50 {
51     scanf("%d%d%d%d%d",&sr,&sg,&sb,&m,&p);
52     n=sr+sg+sb;
53     int ans=0;
54     for(int time=1;time<=m;time++)
55     {
56         for(int i=1;i<=n;i++)scanf("%d",&z[i]);
57         add(ans,calc());
58     }
59     for(int i=1;i<=n;i++)z[i]=i;
60     add(ans,calc());
61     ans*=exp(m+1,p-2,p);ans%=p;
62     printf("%d
",ans);
63     return 0;
64 }
原文地址:https://www.cnblogs.com/zhuohan123/p/3271060.html