zoukankan      html  css  js  c++  java
  • BZOJ1004: [HNOI2008]Cards

    三维01背包算出在每一个置换下不变的染色方案数,Burnside引理计算答案。

    PS:数据太水所以只算恒等置换也是可以过的。

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,p,x,y,z;
    bool u[61];
    int f[21][21][21],s[61],v[61];
    int power(int u,int v){
    	int d=1;
    	for(;v;v>>=1){
    		if(v&1)
    			d=d*u%p;
    		u=u*u%p;
    	}
    	return d;
    }
    void add(int& u,int v){
    	u=(u+v)%p;
    }
    int main(){
    	scanf("%d%d%d%d%d",&x,&y,&z,&m,&p);
    	n=x+y+z;
    	int ans=1;
    	for(int i=1;i<=n;++i)
    		ans=ans*i%p;
    	for(int i=1;i<=x;++i)
    		ans=ans*power(i,p-2)%p;
    	for(int i=1;i<=y;++i)
    		ans=ans*power(i,p-2)%p;
    	for(int i=1;i<=z;++i)
    		ans=ans*power(i,p-2)%p;
    	for(int t=0;t!=m;++t){
    		for(int i=1;i<=n;++i)
    			scanf("%d",s+i);
    		memset(u,0,sizeof u);
    		int cnt=0;
    		for(int i=1;i<=n;++i)
    			if(!u[i]){
    				int k=u[i]=1;
    				for(int j=s[i];j!=i;j=s[j])
    					k+=u[j]=1;
    				v[cnt++]=k;
    			}
    		memset(f,0,sizeof f);
    		f[0][0][0]=1;
    		for(int a=0;a!=cnt;++a)
    			for(int i=x;~i;--i)
    				for(int j=y;~j;--j)
    					for(int k=z;~k;--k){
    						if(i>=v[a])
    							add(f[i][j][k],f[i-v[a]][j][k]);
    						if(j>=v[a])
    							add(f[i][j][k],f[i][j-v[a]][k]);
    						if(k>=v[a])
    							add(f[i][j][k],f[i][j][k-v[a]]);
    					}
    		add(ans,f[x][y][z]);
    	}
    	printf("%d
    ",ans*power(m+1,p-2)%p);
    }
    
  • 相关阅读:
    linux基础
    模块三、企业实战案例
    模块二、shell脚本逻辑结构
    模块一:shell 脚本基础
    三剑客、shell脚本
    定时任务、用户管理、磁盘介绍
    python笔记03
    文件属性、正则表达式、文件权限
    Linux系统目录结构介绍
    Linux基础及入门介绍
  • 原文地址:https://www.cnblogs.com/f321dd/p/5495898.html
Copyright © 2011-2022 走看看