1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<climits> #include<vector> #include<cstdio> #include<cmath> #include<queue>
using namespace std;
inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(!isdigit(x)) { if(x=='-')bj=-1; x=getchar(); } while(isdigit(x)) { num=num*10+x-'0'; x=getchar(); } return num*bj; }
const int maxn=25;
int R,B,G,n,m,p,a[maxn*3],f[maxn][maxn],ans=0; bool vst[maxn*3]; vector<int> cir;
void add(int &x,int v) { x+=v; if(x>=p)x-=p; }
int Quick_Pow(int a,int b) { int ans=1; for(; b; b>>=1,a=a*a%p)if(b&1)ans=ans*a%p; return ans; }
void Bag_Dp() { memset(f,0,sizeof(f)); f[0][0]=1; for(int j=1; j<=cir.size(); j++) { int now=cir[j-1]; for(int a=R; a>=0; a--) for(int b=G; b>=0; b--) { if(a>=now)add(f[a][b],f[a-now][b]); if(b>=now)add(f[a][b],f[a][b-now]); } } add(ans,f[R][G]); }
int main() { R=Get_Int(); G=Get_Int(); B=Get_Int(); m=Get_Int(); p=Get_Int(); n=R+G+B; for(int i=1; i<=m; i++) { fill(vst+1,vst+n+1,0); cir.clear(); for(int j=1; j<=n; j++)a[j]=Get_Int(); for(int j=1; j<=n; j++) if(!vst[j]) { int size=0; for(int k=j; !vst[k]; k=a[k])vst[k]=1,size++; cir.push_back(size); } Bag_Dp(); } cir.clear(); for(int i=1; i<=n; i++)cir.push_back(1); Bag_Dp(); printf("%d\n",ans*Quick_Pow(m+1,p-2)%p); return 0; }
|