三维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\n",ans*power(m+1,p-2)%p);
}

最新文章

  1. yaf框架学习笔记
  2. 说说设计模式~桥梁模式(Bridge)
  3. 《机器学习实战》学习笔记——第2章 KNN
  4. javascript 拷贝文本
  5. UVA 1291 十四 Dance Dance Revolution
  6. android Material Design:主题
  7. jquery 显示“加载状态 结束”
  8. Java的finally理解
  9. JMeter录制脚本
  10. ASP.NET三层架构的分析
  11. 开源 java CMS - FreeCMS2.3 留言管理
  12. iOS之 Auto Layout
  13. bzoj1934
  14. 前端技术之_CSS详解第一天
  15. elementui+vuejs如何添加表格操作按钮
  16. [CSS] input样式定制
  17. python爬虫套件在mac上的安装-bs的安装
  18. sublime快捷键的使用
  19. Linux内核分析第六周总结
  20. 转 Java笔记:Java内存模型

热门文章

  1. md5加密篇(一)
  2. 无线AP和无线路由器区别
  3. JavaScript返回上一级,并重新加载页面
  4. C# Image Resizer
  5. Bootstrap滚动监听
  6. Ubuntu 14.04 安装 JDK 8,ubuntu14.04
  7. java.lang.NullPointerException 空指针异常
  8. javascript 对象实例
  9. linux下mysql基础从安装到基本使用
  10. AOPR弹出Order Now窗口怎么办