[bzoj1004]Cards

置换群。

Burnside引理。

(我不会)

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 using namespace std;
 7 
 8 int Sr,Sg,Sb,m,p,n,cnt,a[100],v[100],size[100],f[30][30][30],ans;
 9 
10 int solve(){
11     memset(v,0,sizeof(v));
12     memset(size,0,sizeof(size));
13     memset(f,0,sizeof(f));
14     cnt=0;
15     for(int i=1;i<=n;i++){
16         if(!v[i]){
17             int j=i;
18             cnt++;
19             do{
20                 v[j]=1;
21                 size[cnt]++;
22                 j=a[j];
23             }while(!v[j]);
24         }
25     }
26     f[0][0][0]=1;
27     for(int i=1;i<=cnt;i++){
28         for(int a=Sr;a>=0;a--){
29             for(int b=Sg;b>=0;b--){
30                 for(int c=Sb;c>=0;c--){
31                     if(a>=size[i])(f[a][b][c]+=f[a-size[i]][b][c])%=p;
32                     if(b>=size[i])(f[a][b][c]+=f[a][b-size[i]][c])%=p;
33                     if(c>=size[i])(f[a][b][c]+=f[a][b][c-size[i]])%=p;
34                 }
35             }
36         }
37     }
38     return f[Sr][Sg][Sb];
39 }
40 
41 int mul(int a,int b){
42     int ret=1;
43     while(b){
44         if(b&1)(ret*=a)%=p;
45         (a*=a)%=p;
46         b>>=1;
47     }
48     return ret;
49 }
50 
51 int main(){
52     scanf("%d%d%d%d%d",&Sr,&Sg,&Sb,&m,&p);
53     n=Sr+Sb+Sg;
54     for(int i=1;i<=m;i++){
55         for(int j=1;j<=n;j++)
56             scanf("%d",&a[j]);
57         (ans+=solve())%=p;
58     }
59     for(int i=1;i<=n;i++)a[i]=i;
60     (ans+=solve())%=p;
61     printf("%d\n",(ans*mul(m+1,p-2))%p);
62 }
View Code

 

posted @ 2017-01-29 14:08  KingSann  阅读(71)  评论(0)    收藏  举报