题目描述

  有\(n\)张卡牌,要求你给这些卡牌染上RGB三种颜色,\(r\)张红色,\(g\)张绿色,\(b\)张蓝色。

  还有\(m\)种洗牌方法,每种洗牌方法是一种置换。保证任意多次洗牌都可用这\(m\)种洗牌法中的一种代

替,且对每种洗牌法,都存在一种洗牌法使得能回到原状态。

  问你本质不同的染色方法有多少种。

  \(r,g,b\leq 20,m\leq 60\)

题解

  对照置换群的定义,可以发现这\(m\)种置换加上恒等置换一共\(m+1\)中置换构成了一个置换群。

  由burnside引理得到本质不同的方案数就是只考虑每个置换时的染色方案数的平均数。

  对于每个置换,先处理出循环,一个循环里的卡牌要染上相同的颜色。因为每种颜色的卡牌有数量限制,所以要背包DP一下。

  最后乘上\({(m+1)}^{-1}\)。

  时间复杂度:\(O(n^3m)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
if(a>b)
swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
int rd()
{
int s=0,c;
while((c=getchar())<'0'||c>'9');
do
{
s=s*10+c-'0';
}
while((c=getchar())>='0'&&c<='9');
return s;
}
int upmin(int &a,int b)
{
if(b<a)
{
a=b;
return 1;
}
return 0;
}
int upmax(int &a,int b)
{
if(b>a)
{
a=b;
return 1;
}
return 0;
}
int p;
int fp(int a,int b)
{
int s=1;
for(;b;b>>=1,a=a*a%p)
if(b&1)
s=s*a%p;
return s;
}
int f[100][100][100];
int a[100];
int r,g,b;
int n;
int c[100];
void add(int &a,int b)
{
a=(a+b)%p;
}
void dp(int v)
{
int i,j,k;
for(i=r;i>=0;i--)
for(j=g;j>=0;j--)
for(k=b;k>=0;k--)
{
if(i>=v)
add(f[i][j][k],f[i-v][j][k]);
if(j>=v)
add(f[i][j][k],f[i][j-v][k]);
if(k>=v)
add(f[i][j][k],f[i][j][k-v]);
}
}
int solve()
{
memset(f,0,sizeof f);
f[0][0][0]=1;
int i;
memset(c,0,sizeof c);
for(i=1;i<=n;i++)
{
int s=0;
int j=i;
while(!c[j])
{
c[j]=1;
s++;
j=a[j];
}
dp(s);
}
return f[r][g][b];
}
int main()
{
int m;
scanf("%d%d%d%d%d",&r,&g,&b,&m,&p);
int i,j;
n=r+g+b;
int ans=0;
for(i=1;i<=m;i++)
{
for(j=1;j<=n;j++)
scanf("%d",&a[j]);
add(ans,solve());
}
m++;
for(i=1;i<=n;i++)
a[i]=i;
add(ans,solve());
ans=ans*fp(m,p-2)%p;
printf("%d\n",ans);
return 0;
}

【BZOJ1004】【HNOI2008】Cards 群论 置换 burnside引理 背包DP的更多相关文章

  1. 【bzoj1004】[HNOI2008]Cards Burnside引理+背包dp

    题目描述 用三种颜色染一个长度为 $n=Sr+Sb+Sg$ 序列,要求三种颜色分别有 $Sr,Sb,Sg$ 个.给出 $m$ 个置换,保证这 $m$ 个置换和置换 ${1,2,3,...,n\choo ...

  2. BZOJ1004: [HNOI2008]Cards(Burnside引理 背包dp)

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4255  Solved: 2582[Submit][Status][Discuss] Descript ...

  3. BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )

    题意保证了是一个置换群. 根据burnside引理, 答案为Σc(f) / (M+1). c(f)表示置换f的不动点数, 而题目限制了颜色的数量, 所以还得满足题目, 用背包dp来计算.dp(x,i, ...

  4. [BZOJ1004][HNOI2008]Cards 群论+置换群+DP

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1004 首先贴几个群论相关定义和引理. 群:G是一个集合,*是定义在这个集合上的一个运算. ...

  5. bzoj1004 [HNOI2008]Cards Burnside 引理+背包

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1004 题解 直接 Burnside 引理就可以了. 要计算不动点的个数,那么对于一个长度为 \ ...

  6. 【BZOJ 1004】 1004: [HNOI2008]Cards (置换、burnside引理)

    1004: [HNOI2008]Cards Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很 ...

  7. [BZOJ1004] [HNOI2008]Cards解题报告(Burnside引理)

    Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红 ...

  8. BZOJ1004 HNOI2008 Cards Burnside、背包

    传送门 在没做这道题之前天真的我以为\(Polya\)可以完全替代\(Burnside\) 考虑\(Burnside\)引理,它要求的是对于置换群中的每一种置换的不动点的数量. 既然是不动点,那么对于 ...

  9. bzoj1004: [HNOI2008]Cards(burnside引理+DP)

    题目大意:3种颜色,每种染si个,有m个置换,求所有本质不同的染色方案数. 置换群的burnside引理,还有个Pólya过几天再看看... burnside引理:有m个置换k种颜色,所有本质不同的染 ...

随机推荐

  1. 通过 sass-resources-loader 全局注册 Sass/Less 变量

    使用webpack引入sass/less全局变量 sass或者less都提供变量设置,在需求切换主题的项目中使用less或者sass变量,只要修改变量值,编译后所有用到该变量的样式都会被修改为你想要的 ...

  2. kuangbin 基础DP集合

    HDU 1024第一遍水过,没有体会到这个题的奥妙,思考了很久终于体会了.大概意思是求把序列分成m段的子序列,并不一定要覆盖完,求子序列和的最大值我们首先要写出基本的动态转移方程: DP:dp[ i ...

  3. C. Painting the Fence

    链接 [https://codeforces.com/contest/1132/problem/C] 题意 就是有个n长的栅栏,然后每个油漆工可以染的区域不同 给你q让你选出q-2个人使得被染色的栅栏 ...

  4. ES5中文分词(IK)

    ElasticSearch5中文分词(IK) ElasticSearch安装 官网:https://www.elastic.co 1.ElasticSearch安装 1.1.下载安装公共密钥 rpm ...

  5. use redis instance in docker hub

    redis - Docker Hubhttps://hub.docker.com/_/redis

  6. Linux基础命令和NAT技术

    yum    yellowdog updater,modified是一种用python写的基于rpm的管理工具 用于解决rpm包的依赖性 要安装编译工具 yum install gcc 库函数:静态库 ...

  7. 一、npm基础

    一.什么是npm? npm 是模块管理工具,可以下载.更新第三方模块,也可以发布自己的模块共替他人使用,主要目的在于分享和重用代码: 二.下载安装node,更新npm node 下载网址  https ...

  8. 深浅copy详解

    一. 前言 在python中,对象的赋值和深浅copy,是有差异的.最终得的值也不同,下面我们就通过几个例子,来看下它们之间的区别. 二. 赋值 list2 = ["jack",2 ...

  9. checkbox保存和赋值

    //货物信息中的表格内容 $.each(trG.find('td input,td select'),function(i,inp){ if($(inp).attr('type')=='checkbo ...

  10. Django Rest framework 框架之解析器

    解析器 序列化***** 请求数据进行校验 对queryset进行序列化处理 分页 路由 视图 渲染器