题目描述

用三种颜色染一个长度为 $n=Sr+Sb+Sg$ 序列,要求三种颜色分别有 $Sr,Sb,Sg$ 个。给出 $m$ 个置换,保证这 $m$ 个置换和置换 ${1,2,3,...,n\choose 1,2,3,...,n}$ 构成一个置换群,求置换后不同构的序列个数模 $p$ 。

$0\le Sr,Sb,Sg\le 20,0\le m\le 60,m+1\le p\le 100$ ,$p$ 是质数。

输入

第一行输入 5 个整数:Sr,Sb,Sg,m,p(m<=60,m+1<p<100)。n=Sr+Sb+Sg。
接下来 m 行,每行描述一种洗牌法,每行有 n 个用空格隔开的整数 X1X2...Xn ,恰为 1 到 n 的一个排列,表示使用这种洗牌法,第 i 位变为原来的 Xi 位的牌。输入数据保证任意多次洗牌都可用这 m 种洗牌法中的一种代替,且对每种洗牌法,都存在一种洗牌法使得能回到原状态。

输出

不同染法除以P的余数

样例输入

1 1 1 2 7
2 3 1
3 1 2

样例输出

2


题解

Burnside引理+背包dp

由于颜色有3种,因此不能直接使用Polya定理。

考虑Burnside引理推导Polya定理的过程:对于一种置换,不动点需要满足:每个循环种的颜色相同。

这种推导即可应用于本题。我们对于一个置换,取出其所有循环,这个循环需要 循环大小 个同种颜色。

显然是一个背包dp。设 $f[i][j][k]$ 表示前 $i$ 个置换,用了 $j$ 种颜色1和 $k$ 种颜色2的方案数(用了 $sum_i-j-k$ 种颜色3)。那么对于第 $i$ 个置换,讨论其颜色即可转移。

最终对于该置换的不动点数目即为 $f[k][Sr][Sb]$ ,$k$ 为循环数目。

把所有置换(包括置换后得到本身的置换 ${1,2,3,...,n\choose 1,2,3,...,n}$ )的不动点数目加起来,乘以 $m$ 的逆元即为答案。

时间复杂度 $O(mn^3)$

#include <cstdio>
#include <cstring>
int a , b , c , p , f[65][25][25] , v[65] , vis[65];
int solve()
{
int tot = 0 , sum = 0 , w , i , j , k;
memset(vis , 0 , sizeof(vis));
memset(f , 0 , sizeof(f));
f[0][0][0] = 1;
for(i = 1 ; i <= a + b + c ; i ++ )
{
if(!vis[i])
{
tot ++ ;
for(w = 0 , j = i ; !vis[j] ; j = v[j])
vis[j] = 1 , w ++ ;
sum += w;
for(j = 0 ; j <= a ; j ++ )
{
for(k = 0 ; k <= b ; k ++ )
{
if(sum - j - k <= c)
{
if(j >= w) f[tot][j][k] += f[tot - 1][j - w][k];
if(k >= w) f[tot][j][k] += f[tot - 1][j][k - w];
if(sum - j - k >= w) f[tot][j][k] += f[tot - 1][j][k];
f[tot][j][k] %= p;
}
}
}
}
}
return f[tot][a][b];
}
int main()
{
int m , i , j , ans = 0;
scanf("%d%d%d%d%d" , &a , &b , &c , &m , &p);
for(i = 1 ; i <= a + b + c ; i ++ ) v[i] = i;
ans = solve();
for(i = 1 ; i <= m ; i ++ )
{
for(j = 1 ; j <= a + b + c ; j ++ ) scanf("%d" , &v[j]);
ans = (ans + solve()) % p;
}
for(i = 1 ; i <= p - 2 ; i ++ ) ans = ans * (m + 1) % p;
printf("%d\n" , ans);
return 0;
}

我才不会告诉你们下面的代码也能过呢(数据太水了 = =)

#include <cstdio>
int p;
int pow(int x , int y)
{
int ans = 1;
while(y)
{
if(y & 1) ans = ans * x % p;
x = x * x % p , y >>= 1;
}
return ans;
}
int main()
{
int a , b , c , m , i , ans = 1;
scanf("%d%d%d%d%d" , &a , &b , &c , &m , &p);
for(i = 1 ; i <= a + b + c ; i ++ ) ans = ans * i % p;
for(i = 1 ; i <= a ; i ++ ) ans = ans * pow(i , p - 2) % p;
for(i = 1 ; i <= b ; i ++ ) ans = ans * pow(i , p - 2) % p;
for(i = 1 ; i <= c ; i ++ ) ans = ans * pow(i , p - 2) % p;
ans = ans * pow(m + 1 , p - 2) % p;
printf("%d\n" , ans);
return 0;
}

【bzoj1004】[HNOI2008]Cards Burnside引理+背包dp的更多相关文章

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

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

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

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

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

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

  4. BZOJ1004 HNOI2008 Cards Burnside、背包

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

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

    题目传送门 思路:首先是Burnside引理,要先学会这个博客. Burnside引理我们总结一下,就是 每种置换下不动点的数量之和除以置换的总数,得到染色方案的数量.        这道题,显然每种 ...

  6. 【BZOJ1004】【HNOI2008】Cards 群论 置换 burnside引理 背包DP

    题目描述 有\(n\)张卡牌,要求你给这些卡牌染上RGB三种颜色,\(r\)张红色,\(g\)张绿色,\(b\)张蓝色. 还有\(m\)种洗牌方法,每种洗牌方法是一种置换.保证任意多次洗牌都可用这\( ...

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

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

  8. 【BZOJ1004】[HNOI2008]Cards Burnside引理

    [BZOJ1004][HNOI2008]Cards 题意:把$n$张牌染成$a,b,c$,3种颜色.其中颜色为$a,b,c$的牌的数量分别为$sa,sb,sc$.并且给出$m$个置换,保证这$m$个置 ...

  9. luogu P1446 [HNOI2008]Cards burnside引理 置换 不动点

    LINK:Cards 不太会burnside引理 而这道题则是一个应用. 首先 一个非常舒服的地方是这道题给出了m个本质不同的置换 然后带上单位置换就是m+1个置换. burnside引理: 其中D( ...

随机推荐

  1. POJ2513_Colored Sticks_KEY

    题目传送门 题目大意:给你若干根木棍,每根木棍有前后两种颜色,连接两根木棍需要前后颜色相同,求能否将所有木棍连接在一起. Solution: 不要将木棍看成点,将颜色看成点. 其实就是求是否存在欧拉路 ...

  2. day1 RHCE

    1.环境部署 classroom.example.com: 172.25.0.254 root Asimov server0.example.com: 172.25.0.11 root redhat ...

  3. 【LG1445】樱花

    [LG1445]樱花 题面 洛谷 题解 \[ \frac 1x+\frac 1y=\frac 1{n!}\\ \frac{x+y}{xy}=\frac 1{n!}\\ n!(x+y)=xy\\ xy- ...

  4. 海思NB-IOT的SDK函数使用说明

    1. 查询当前AT指令是否正在处理中 while(get_at_cmd_in_progress() == false); 2. 信号量发送函数 (, osNoWait); 3. 信号量接收函数 if( ...

  5. 数据库路由中间件MyCat - 源代码篇(15)

    此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. public static void handle(String stmt, ServerConnectio ...

  6. Vue学习计划基础笔记(二) - 模板语法,计算属性,侦听器

    模板语法.计算属性和侦听器 目标: 1.熟练使用vue的模板语法 2.理解计算属性与侦听器的用法以及应用场景 1. 模板语法 <div id="app"> <!- ...

  7. Java飞机大战MVC版

    PlaneWar Java飞机大战MVC版 //无聊时偷的雷霆战机素材写了一个飞机大战,本意是练习mvc,但写得还是不清晰 github下载:https://github.com/dejavudwh/ ...

  8. Throwable、Error、Exception、RuntimeException的区别与联系

    Throwable类是Java语言中所有错误和异常的超类.只有作为此类(或其子类之一)的实例的对象才被Java虚拟机抛出,或者可以被Java throw语句抛出.类似地,只有这个类或其子类之一可以是c ...

  9. 广东ACM省赛 E题

    题意: 输入一个P 使得存在一个一个N大于等于P, 并且存在m 等于 m/n * (m-1)/(n-1)=1/2. 思路 此题可以利用佩尔方程求解, 也可以打表解决.本次我解决利用的是佩尔方程(其实也 ...

  10. website for personal research

    YOLO https://pjreddie.com/darknet/yolo/ Low Rank Matrix Recovery and Completion via Convex Optimizat ...