首页 > 代码库 > BZOJ1004

BZOJ1004

来自蒟蒻XXJ的做题记录

这个东西 ====

我能说我看了很久的证明都没有看懂吗w 但是PhoenixEclipse巨巨好像想出了证明 %%%%% @PhoenixEclipse【也不知道会不会蓝

首先 Burnsid引理 大概都知道w 不知道的去问问度娘

然后呢我在考虑证明的时候好像就考虑到了w如果这个元素对于这种置换是个不动点,那么一定有,在这个元素里面w置换所成的环里面的东西都是一样的【绕

说简单一点w就是怎么转都是不会改变这个里面的东西的顺序的w才叫不动点w不改变顺序w必须里面都相等w

然后就是怎么把这三种颜色的东西给放到里面去了w这个东西写一个DP算一下方案数就好了w很简单的背包 然后为了空间节省w再像01背包那样优化掉一维空间就好了w

于是,出现吧代码君!@代码君【我管你蓝不蓝

`#include<bits/stdc++.h>
#define mem(i,j) memset(i,j,sizeof(i))
using namespace std;
typedef long long ll;
ll in(){
    ll a(0);char c=getchar();
    while(c<‘0‘||c>‘9‘) c=getchar();
    while(c>=‘0‘&&c<=‘9‘) a=(a<<1)+(a<<3)+c-‘0‘,c=getchar();
    return a;
}
void extgcd(ll a,ll b,ll &x,ll &y){
    if(!b){
        x=1;y=0;
        return;
    }
    else{
        extgcd(b,a%b,y,x);
        y-=(a/b)*x;
    }
}
ll rev(ll a,ll m){
    ll x,y;
    extgcd(a,m,x,y);
    return (x%m+m)%m;
}
ll n,m,MOD;
ll s1,s2,s3;
ll cyc[64][64],top[64],dp[32][32][32];
ll cycle[64],ans;
bool vis[64];
void input(){
    s1=in();s2=in();s3=in();m=in();MOD=in();
    n=s1+s2+s3;
    for(ll i=0;i<m;i++){
        mem(vis,0);
        for(ll j=1;j<=n;j++) cycle[j]=in();
        for(ll j=1;j<=n;j++){
            if(vis[j]) continue;
            ll len(0),now=j;
            while(!vis[now]){
                ++len;vis[now]=1;
                now=cycle[now];
            }
            cyc[i][++top[i]]=len;
        }
    }
    for(ll i=1;i<=n;i++) cyc[m][i]=1;
    top[m]=n;
}
ll domicp(ll now){
    mem(dp,0);
    dp[0][0][0]=1;
    for(ll h=1;h<=top[now];++h){
        ll del=cyc[now][h];
        for(ll i=s1;i>=0;--i)for(ll j=s2;j>=0;--j)for(ll k=s3;k>=0;--k){
            if(!i&&!j&&!k) continue;
            if(i-del>=0) dp[i][j][k]=(dp[i][j][k]+dp[i-del][j][k])%MOD;
            if(j-del>=0) dp[i][j][k]=(dp[i][j][k]+dp[i][j-del][k])%MOD;
            if(k-del>=0) dp[i][j][k]=(dp[i][j][k]+dp[i][j][k-del])%MOD;
        }
    }
    return dp[s1][s2][s3];
}
void xxj(){
    ll sum(0);
    for(ll i=0;i<=m;i++)
        sum=(sum+domicp(i))%MOD;
    ll revv=rev((m+1),MOD);
    ans=revv*sum;ans%=MOD;
}
void output(){
    printf("%lld\n",ans);
}

int main(){
    input();
    xxj();
    output();
    return 0;
}`

BZOJ1004