[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 }