Face questions
The meaning of problems
Given \ (a, b, c \ ) the number of cards represent three colors, now given \ (m \) permutation, we obtain the number of substitutions at the different nature of these card arrangement. Guaranteed for any permutation satisfies a given displacement there is a substitution to change back to the original state, and any combination of substitutions can be replaced with a replacement.
answer
Basically bare of Burnside problem. The \ ((1,2, \ dots, n) \) was added \ (m \) permutation in accordance of Burnside, such \ (m + 1 \) equivalence classes under substitutions (i.e. essentially a different arrangement of the number of cards) is equal to \ (m + 1 \) substitutions on the fixed point (i.e. no change in the arrangement of one permutation) the number of average.
So the question becomes how to find the number of transformed every permutation in the fixed point. Replacement of the \ (I \) bit \ (x_i \) seen from the \ (I \) is connected to the \ (x_i \) of one side of a one-way, you can get a \ (n-\) nodes, there are a number of rings to FIG. We found that, if the arrangement does not change in a substitution on the ring, then all cards are the same color. We can convert the problem to a color ring, to meet the number of nodes in each of the three colors \ (a, b, c \ ) number scheme. This problem can be solved with a three-dimensional backpack.
Code
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int maxn=25,maxm=65;
int mod;
int dp[maxn][maxn][maxn];
int pow(int a,int b){
int ans=1;
while (b){
if (b&1) ans=ans*a%mod;
a=a*a%mod; b>>=1;
}
return ans;
}
int inv(int n){ return pow(n,mod-2); }
int x[maxm];
bool vis[maxm];
vector<int> vec;
int a,b,c,n;
void get(){
int i,u,cnt;
vec.clear();
for (i=1;i<=n;i++) vis[i]=false;
for (i=1;i<=n;i++) if (!vis[i]){
u=x[i]; cnt=1; vis[u]=true;
while (u!=i){
u=x[u]; cnt++; vis[u]=true;
}
vec.push_back(cnt);
}
}
int solve(){
int i,j,k,v,p;
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
for (p=0;p<vec.size();p++){
v=vec[p];
for (i=a;i>=0;i--) for (j=b;j>=0;j--) for (k=c;k>=0;k--){
if (i>=v) dp[i][j][k]+=dp[i-v][j][k];
if (j>=v) dp[i][j][k]+=dp[i][j-v][k];
if (k>=v) dp[i][j][k]+=dp[i][j][k-v];
dp[i][j][k]%=mod;
}
}
return dp[a][b][c];
}
int main(){
int i,j,m;
int ans;
scanf("%d%d%d%d%d",&a,&b,&c,&m,&mod);
n=a+b+c;
vec.resize(n);
for (i=0;i<n;i++) vec[i]=1;
ans=solve();
for (i=0;i<m;i++){
for (j=1;j<=n;j++) scanf("%d",&x[j]);
get();
ans+=solve();
}
ans=ans%mod*inv(m+1)%mod;
printf("%d\n",ans);
return 0;
}