BZOJ 1004 Cards

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

Guess you like

Origin www.cnblogs.com/Kilo-5723/p/12004106.html