[BZOJ1004]Cards

  polya定理+乘法逆元

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 65
 4 #define maxs 25
 5 int sr,sb,sg,n,m,p;
 6 int a[maxn][maxn],f[maxs][maxs][maxs],vis[maxn],cal[maxn];
 7 
 8 int dp(int x){
 9     memset(vis,0,sizeof(vis));
10     memset(f,0,sizeof(f));
11     int cc=0;
12     for(int i=1;i<=n;i++){
13         if(!vis[i]){
14             vis[i]=1;
15             cal[++cc]=1;
16             int ii=i;
17             while(!vis[a[x][ii]]){
18                 vis[a[x][ii]]=1;
19                 cal[cc]++;
20                 ii=a[x][ii];
21             }
22         }
23     }
24     f[0][0][0]=1;
25     for(int t=1;t<=cc;t++)
26         for(int i=sr;i>=0;i--)
27             for(int j=sb;j>=0;j--)
28                 for(int k=sg;k>=0;k--){
29                     if(i>=cal[t])f[i][j][k]=(f[i][j][k]+f[i-cal[t]][j][k])%p;
30                     if(j>=cal[t])f[i][j][k]=(f[i][j][k]+f[i][j-cal[t]][k])%p;
31                     if(k>=cal[t])f[i][j][k]=(f[i][j][k]+f[i][j][k-cal[t]])%p;
32                 }
33     return f[sr][sb][sg];
34 }
35 int main(){
36     scanf("%d%d%d%d%d",&sr,&sb,&sg,&m,&p);
37     n=sr+sb+sg;
38     for(int i=1;i<=m;i++)
39         for(int j=1;j<=n;j++)
40             scanf("%d",&a[i][j]);
41     m++;
42     for(int i=1;i<=n;i++)a[m][i]=i;
43     int ans=0;
44     for(int i=1;i<=m;i++)
45         ans=(ans+dp(i))%p;
46     for(int i=1;i<=p-2;i++)
47         ans=(ans*m)%p;
48     printf("%d
",ans);
49     return 0;
50 }
View Code
原文地址:https://www.cnblogs.com/Ngshily/p/5075708.html