CF140E New Year Garland (计数问题)
用$m$种颜色的彩球装点$n$层的圣诞树。圣诞树的第$i$层恰由$a_{i}$个彩球串成一行,且同一层内的相邻彩球颜色不同,同时相邻两层所使用彩球的颜色集合不 同。求有多少种装点方案,答案对$p$取模。
好神的计数问题,zwz Orz
题解思路来自黄学长hzwer的博客
先只考虑在一行内的彩球的方案数
定义$g[i][j]$表示一共有$i$个球串成一行,一共用了$j$种颜色的方案数
因为所有颜色都是等价的,我们可以利用最小表示法来简化计数,比如让颜色编号为$x+1$的球第一次出现的位置,在颜色编号为$x$的球之前。实际的方案数是$g[i][j]\cdot j!$
这样递推关系就简单多了
加入一个新颜色的球,$g[i][j]+=g[i-1][j-1]$
加入一个旧颜色的球,颜色不能和第$i-1$个球相同,$g[i][j]+=(j-1)g[i-1][j]$
$g[i][j]=g[i-1][j-1]+(j-1)g[i-1][j]$
在考虑行行之间的影响
定义$f[i][j]$表示前$i$行,其中第$i$行选了$j$种颜色的方案数
如果没有相邻两行集合不同这种限制
$f[i][j]=C_{m}^{j}\cdot g[a_{i}][j]\cdot \sum f[i-1][k]$
如果加上限制,
$f[i][j]=C_{m}^{j}\cdot g[a_{i}][j]\cdot j!\sum f[i-1][k]-g[a_{i}][j]\cdot j!\cdot f[i-1][j]$
$=A_{m}^{j}\cdot g[a_{i}][j]\sum f[i-1][k]-g[a_{i}][j]\cdot j!\cdot f[i-1][j]$
利用前缀和优化可以$O(1)$转移
$f[i][j]$的状态数也仅仅是$O(\sum a_{i})$,用滚动数组记录
$A_{m}^{j}$和$j!$可以通过预处理得到
总结:由于本题的模数是非质数,用组合数计数会让问题变得复杂,且时间复杂度很难保证。如果本题保证模数为质数,可能会有很多其他做法,比如组合数+容斥等等,但应该都没有官方题解的思路简洁。出题者似乎引导我们走向突破口——消去组合数,突破口在于通过化简,把组合数化成排列数和阶乘,排列数和阶乘即使在模数为非质数的情况下,也能在$O(n)$时间预处理
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 5010
#define M1 1000010
#define dd double
#define ll long long
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
int n,m,mx,P; int f[][N1],g[N1][N1],am[N1],mul[N1],a[M1]; int main()
{
int i,j,x;
scanf("%d%d%d",&n,&m,&x);
for(i=;i<=n;i++) scanf("%d",&a[i]), mx=max(mx,a[i]);
const int p=x;
g[][]=g[][]=;
for(i=;i<=mx;i++) for(j=;j<=i;j++) g[i][j]=(1ll*(j-)*g[i-][j]%p+g[i-][j-])%p;
mul[]=mul[]=; am[]=;
for(i=;i<=min(m,mx);i++) am[i]=1ll*am[i-]*(m-i+)%p;
for(i=;i<=mx;i++) mul[i]=1ll*mul[i-]*i%p;
int now=,pst=,snow=,spst=;
f[pst][]=;
for(i=;i<=n;i++)
{
snow=;
for(j=;j<=min(m,a[i]);j++)
f[now][j]=(1ll*am[j]*g[a[i]][j]%p*spst%p-1ll*f[pst][j]*mul[j]%p*g[a[i]][j]%p+p)%p, (snow+=f[now][j])%=p;
memset(f[pst],,(min(m,a[i-])+)<<);
swap(now,pst); swap(snow,spst);
}
printf("%d\n",spst);
return ;
}
CF140E New Year Garland (计数问题)的更多相关文章
- [cf140e]New Year Garland
Description 用$m$种颜色的彩球装点$n$层的圣诞树.圣诞树的第$i$层恰由$l[i]$个彩球串成一行,且同一层内的相邻彩球颜色不同,同时相邻两层所使用彩球的颜色集合不同. 求有多少种装点 ...
- 一些gcd计数问题
数论什么的全都忘光了吧QAQ 做了几道简单的题练习一下. bzoj1101: [POI2007]Zap 求有多少对数满足 gcd(x,y)=d, 1<=x<=a, 1<=y<= ...
- POJ 1759 Garland(二分+数学递归+坑精度)
POJ 1759 Garland 这个题wa了27次,忘了用一个数来储存f[n-1],每次由于二分都会改变f[n-1]的值,得到的有的值不精确,直接输出f[n-1]肯定有问题. 这个题用c++交可以 ...
- poj 1759 Garland (二分搜索之其他)
Description The New Year garland consists of N lamps attached to a common wire that hangs down on th ...
- 扩展Python模块系列(四)----引用计数问题的处理
承接上文,发现在使用Python C/C++ API扩展Python模块时,总要在各种各样的地方考虑到引用计数问题,稍不留神可能会导致扩展的模块存在内存泄漏.引用计数问题是C语言扩展Python模块最 ...
- poj 1759 Garland
Garland Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2365 Accepted: 1007 Descripti ...
- 置换群、Burnside引理与等价类计数问题
置换群.Burnside引理与等价类计数问题 标签: 置换群 Burnside引理 置换 说说我对置换的理解,其实就是把一个排列变成另外一个排列.简单来说就是一一映射.而置换群就是置换的集合. 比如\ ...
- C. Nice Garland Codeforces Round #535 (Div. 3) 思维题
C. Nice Garland time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
- D. Diverse Garland Codeforces Round #535 (Div. 3) 暴力枚举+贪心
D. Diverse Garland time limit per test 1 second memory limit per test 256 megabytes input standard i ...
随机推荐
- sublime text 插件emmet快捷命令
原文链接:http://www.17yaobai.com/?p=255 语法: 后代:> 缩写:nav>ul>li <nav> <ul> <li> ...
- MEAN框架学习笔记
MEAN框架学习笔记 MEAN开发框架的资料非常少.基本的资料还是来自于learn.mean.io站点上的介绍. 于是抱着一种零基础学习的心态,在了解的过程中,通过翻译加上理解将MEAN框架一点点消化 ...
- HDU 4517
EASY题,直接统计(1,1)到(i,j)的黑点个数,然后计算出以(i,j)点为右下角的矩形内的黑点个数是x*y即可. 注意当x==y时不要重复统计. #include <iostream> ...
- 7种炫酷HTML5 SVG液态水滴融合分解动画特效
这是一组使用HTML5 SVG过滤器制作的炫酷液态水滴融合分解动画特效.这些SVG动画特效使一些HTML元素.如菜单.分页button.APP.选择框等元素的过渡动画像几粒水滴一样融合分解.效果很的酷 ...
- nginx源代码分析--进程间通信机制 & 同步机制
Nginx源代码分析-进程间通信机制 从nginx的进程模型能够知道.master进程和worker进程须要通信,nginx中通信的方式有套接字.共享内存.信号.对于master进程,从外部接受信号, ...
- Codeforces Round #349 (Div. 2) D. World Tour 暴力最短路
D. World Tour A famous sculptor Cicasso goes to a world tour! Well, it is not actually a world-wid ...
- 控制台中使用SetTimer的提醒
SetTimer是设置定时器,每隔一段时间执行一个操作,原型如下 UINT_PTR SetTimer( HWND hWnd, // 窗口句柄 UINT_PTR nIDEvent, // 定时器ID,多 ...
- 何时使用static类(工具类)
一个static类,指所有成员都是static方法构成的.而没有不论什么成员变量, 也称为Utility class 或者Utility Pattern [參考: Utility Pattern].它 ...
- javascript定义类或对象的方式
本文介绍的几种定义类或对象的方式中,目前使用最广泛的是:混合的构造函数/原型方式.动态原型方式.不要单独使用经典的构造函数或原型方式. 工厂方式 构造器函数 原型方式 混合的构造函数/原型方式 动态原 ...
- My first blog for java
我的第一个java程序: package com.hellojava; /** * @author 沽-名-钓-誉 */ public class HelloJava{ /** * @param 输出 ...