【HNOI2008】Cards BZOJ 1004
Description
小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目 前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红色,Sb张蓝色,Sg张绝 色.他又询问有多少种方案,Sun想了一下,又给出了正确答案. 最后小春发明了M种不同的洗牌法,这里他又问Sun有多少种不同的染色方案.两种染色方法相同当且仅当其中一种可以通过任意的洗牌法(即可以使用多种洗牌 法,而每种方法可以使用多次)洗成另一种.Sun发现这个问题有点难度,决定交给你,答案可能很大,只要求出答案除以P的余数(P为质数).
Input
第一行输入 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种洗牌法中的一种代替,且对每种
洗牌法,都存在一种洗牌法使得能回到原状态。
Output
不同染法除以P的余数
Sample Input
2 3 1
3 1 2
Sample Output
HINT
有2 种本质上不同的染色法RGB 和RBG,使用洗牌法231 一次可得GBR 和BGR,使用洗牌法312 一次 可得BRG 和GRB。
100%数据满足 Max{Sr,Sb,Sg}<=20。
思路
嘛~首先可以看到是组合数学的题目。之后就想大概是个什么模型。
看到在一个排列中元素可以交换,就想到了置换群,Polya计数法。
那么就是有这么多给你的置换方法,求本质上不同的排列有多少。我们将每一个置换群分解,找出置换的循环节:
比如置换1 4 3 5 2可以分解为(1)(2 4 5)(3)这三个循环节。
由polya计数法得:ans=所有置换中本质相同的方案的平均数。
看到100%数据满足 Max{Sr,Sb,Sg}<=20可以用dp做。
用f[i][j][k]表示用了i个红色,j个绿色,k个蓝色的方案数,则f[i][j][k]=f[i-size][j][k]+f[i][j-size][k]+f[i][j][k-size](size是当前循环节的大小)
最后不要忘记加上(1 2 3 ....n)这个循环,这个可以直接算出有N!/(sr!*sg!*sb!)
然后除以m+1,p为质数,用逆元算。
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <list>
#include <vector>
#include <ctime>
#include <functional>
#define pritnf printf
#define scafn scanf
#define For(i,j,k) for(int i=(j);i<=(k);(i)++)
#define Clear(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long LL;
typedef unsigned int Uint;
const int INF=0x7fffffff;
//==============struct declaration============== //==============var declaration=================
const int MAXN=;
int sr,sb,sg,n,m,p,MOD,cnt=;
int ans=;
int tran[MAXN*];
int f[MAXN][MAXN][MAXN];
bool vis[MAXN*];
//==============function declaration============
int quickpow(int a,int Exp);
int inv(int a){return quickpow(a,MOD-);}
int fact(int x){int ans=;for(int i=;i<=x;i++) ans=(ans*i)%MOD;return ans;}
//==============main code=======================
int main()
{
//#define FILE__
#ifdef FILE__
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
#endif
scanf("%d%d%d%d%d",&sr,&sb,&sg,&m,&MOD);n=sr+sb+sg;
for(int i=;i<=m;i++){
for(int j=;j<=n;j++)
scanf("%d",tran+j);
memset(vis,false,sizeof(vis));memset(f,,sizeof(f));
f[][][]=;cnt=;
for(int p=;p<=n;p++){
if (vis[p]) continue;
cnt++;
int siz=,x=p;
while (!vis[x]){
vis[x]=true;
x=tran[x];
siz++;
}//找出循环节
for(int i=sr;i>=;i--)
for(int j=sb;j>=;j--)
for(int k=sg;k>=;k--){
if (i>=siz) f[i][j][k]+=f[i-siz][j][k];
if (j>=siz) f[i][j][k]+=f[i][j-siz][k];
if (k>=siz) f[i][j][k]+-f[i][j][k-siz];
f[i][j][k]%=MOD;
} //DP
}
ans=(ans+f[sr][sb][sg])%MOD;
}
ans=ans+fact(n)*inv(fact(sr))*inv(fact(sb))*inv(fact(sg));
printf("%d\n",(ans*inv(m+))%MOD);
return ;
}
//================fuction code====================
int quickpow(int a,int Exp){
if (Exp==) return ;
if (Exp==) return a;
int temp=quickpow(a,Exp/);
temp=(temp*temp)%MOD;
if (Exp&) temp=(temp*a)%MOD;
return temp;
}
Code
【HNOI2008】Cards BZOJ 1004的更多相关文章
- 【BZOJ】【1004】【HNOI2008】Cards
Burnside/Polya+背包DP 这道题目是等价类计数裸题吧……>_> 题解:http://m.blog.csdn.net/blog/njlcazl_11109/8316340 啊其 ...
- BZOJ 1004 【HNOI2008】 Cards
题目链接:Cards 听说这道题是染色问题的入门题,于是就去学了一下\(Bunside\)引理和\(P\acute{o}lya\)定理(其实还是没有懂),回来写这道题. 由于题目中保证"任意 ...
- 【BZOJ1004】【HNOI2008】Cards 群论 置换 burnside引理 背包DP
题目描述 有\(n\)张卡牌,要求你给这些卡牌染上RGB三种颜色,\(r\)张红色,\(g\)张绿色,\(b\)张蓝色. 还有\(m\)种洗牌方法,每种洗牌方法是一种置换.保证任意多次洗牌都可用这\( ...
- 【BZOJ1010】【HNOI2008】玩具装箱(斜率优化,动态规划)
[BZOJ1010][HNOI2008]玩具装箱 题面 题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一 ...
- 【BZOJ1004】Cards(组合数学,Burnside引理)
[BZOJ1004]Cards(组合数学,Burnside引理) 题面 Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Su ...
- Cards BZOJ 1004
Cards [问题描述] 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张 ...
- 【BZOJ】【1009】 【HNOI2008】GT考试
DP/KMP/矩阵乘法 好神的题啊……跪了跪了 $n\leq 10^9$是什么鬼……我们还是先不要考虑这个鬼畜的玩意了>_> 用类似数位DP的思路,我们可以想到一个DP方程:$f[i][j ...
- 【BZOJ】【1010】【HNOI2008】玩具装箱Toy
DP/斜率优化 根据题目描述很容易列出动规方程:$$ f[i]=min\{ f[j]+(s[i]-s[j]+i-j-1-L)^2 \}$$ 其中 $$s[i]=\sum_{k=1}^{i} c[k] ...
- 【BZOJ】【1005】【HNOI2008】明明的烦恼
Prufer序列/排列组合+高精度 窝不会告诉你我是先做了BZOJ1211然后才来做这题的>_>(为什么?因为我以前不会高精度呀……) 在A了BZOJ 1211和1089之后,蒟蒻终于有信 ...
随机推荐
- 从贝叶斯到粒子滤波——Round 2
上一篇博文已经讲了贝叶斯滤波的原理以及公式的推导:http://www.cnblogs.com/JunhaoWu/p/bayes_filter.html 本篇文章将从贝叶斯滤波引入到粒子滤波,讲诉粒子 ...
- 浅谈对Spring Framework的认识
Spring Framework,作为一个应用框架,官方的介绍如下: The Spring Framework provides a comprehensive programming and con ...
- .Net Core Linux centos7行—安装nginx,运行静态网站
使用编译安装方式安装nginx Nginx下载地址:http://nginx.org/en/download.html.下载Stable version(稳定版就好).当前稳定版:http://ngi ...
- spring-初始化完成后运行指定内容
方案1:继承ApplicationListener public class InstantiationTracingBeanPostProcessor implements ApplicationL ...
- UML类图详解
下面是类图的实例: (注:飞翔接口那里应为空心三角形) UML中类图实例 接口:空心圆+直线(唐老鸭类实现了‘讲人话’):依赖:虚线+箭头(动物和空气的关系):关联:实线+箭头(企鹅需要知道气候才迁移 ...
- 上网八个常用cmd命令你掌握了几个?
上网八个常用cmd命令你掌握了几个? 一.ping 它是用来检查网络是否通畅或者网络连接速度的命令.作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握 ...
- 构建自己的 Linux 发行版
如何用 SUSE Studio 构建 Linux 发行版? (1) 进入到 www.susestudio.com,设立一个帐户 (2) 为你的设备(发行版)选择一个基本模板 -软件和软件包选择 (1) ...
- NSUserDefaults:熟悉与陌生(转)
转载自:http://swiftcafe.io/2016/04/04/nsuserdefaults/?hmsr=toutiao.io&utm_medium=toutiao.io&utm ...
- rcync 备份命令
不写复杂的命令参数什么意思,网上一搜一大堆. 这是我用的命令: rsync -ax --progress -e "ssh -p 12345" --delete root@143.2 ...
- 让你Android开发更简单
转载:http://www.jianshu.com/p/22ff8b5fdadc 搭建一个新的Android项目,你会怎么做? 每个人对应用框架的理解不相同,但是最终达到的效果应该是一样: ①降低项目 ...