bzoj 1004

计数好题

首先看到这种问题直接想到的应该是polya定理

可是对颜色使用个数有限制啊!

没关系,我们分析一下polya定理的表达式:

$\frac{1}{|G|}\sum_{i=1}^{n}m^{c_{i}}$

可以看到,这其中的每一项等价于用$m$种颜色对每个循环节任意染色的方案数(即对每个循环节内的元素染成相同颜色的方案数)

因此对于这个有限制的问题,我们可以用简单的背包求出这一方案数

最后对方案数求和,乘个逆元即可

注意:不要忘了群的基本定义,一个置换群里是需要单位元的,因此需要补充一个原始置换

代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
using namespace std;
ll sr,sb,sg,m,p;
int to[65];
bool vis[65];
int siz[65][65];
ll f[65][25][25][25];
int val[65];
ll pow_mul(ll x,ll y)
{
    ll ret=1;
    while(y)
    {
        if(y&1)ret=ret*x%p;
        x=x*x%p,y>>=1;
    }
    return ret;
}
int main()
{
    scanf("%lld%lld%lld%lld%lld",&sr,&sb,&sg,&m,&p);
    ll n=sr+sb+sg;
    for(int i=1;i<=m;i++)
    {
        for(int j=1;j<=n;j++)scanf("%d",&to[j]);
        memset(vis,0,sizeof(vis));
        for(int j=1;j<=n;j++)
        {
            int p=j;
            if(vis[p])continue;
            val[i]++;
            while(!vis[p])
            {
                siz[i][val[i]]++;
                vis[p]=1;
                p=to[p];
            }
        }
    }    
    m++;
    val[m]=n;
    for(int i=1;i<=n;i++)siz[m][i]=1;
    ll s=0;
    for(int t=1;t<=m;t++)//枚举第几个循环 
    {
        ll S=0;
        memset(f,0,sizeof(f));
        f[0][0][0][0]=1;
        for(int i=1;i<=val[t];i++)
        {
            S+=siz[t][i];
            for(int j=0;j<=sr;j++)//枚举红色的个数 
            {
                for(int k=0;k<=sb;k++)
                {
                    if(S-j-k>sg)continue;
                    if(j>=siz[t][i])f[i][j][k][S-j-k]+=f[i-1][j-siz[t][i]][k][S-j-k];
                    if(k>=siz[t][i])f[i][j][k][S-j-k]+=f[i-1][j][k-siz[t][i]][S-j-k];
                    if(S-j-k>=siz[t][i])f[i][j][k][S-j-k]+=f[i-1][j][k][S-j-k-siz[t][i]];
                    f[i][j][k][S-j-k]%=p;                
                }
            }
        }
        s+=f[val[t]][sr][sb][sg];
        s%=p;
    }
    s=s*pow_mul(m,p-2)%p;
    printf("%lld\n",s);
    return 0;
}

 

posted @ 2019-06-12 18:05  lleozhang  Views(191)  Comments(0Edit  收藏  举报
levels of contents