[CSP-S模拟测试]:长寿花(DP+组合数)
题目描述
庭院里有一棵古树。
圣诞节到了,我想给古树做点装饰,给他一个惊喜。
他会不会喜欢呢?
这棵树可以分为$n$层,第$i$层有$a_i$个防治装饰品的位置,有$m$种颜色的装饰品可供选择。
为了能让他喜欢,我想让装饰品满足以下条件:
$1.$在同一层两个相邻的装饰品不能有同一种颜色;
$2.$相邻两层的颜色集合不能相同(这里颜色集合是指这一层所有出现的颜色去重之后的集合,也就是每个颜色只在集合被最多出现一次)。
我想知道,有多少种不同的方案能让他满意呢?由于方案书可能很多,请告诉我模$p$之后的答案。
谢谢你。
输入格式
第一行三个整数,$n,m,p$。
第二行$n$个整数,第$i$个整数表示$a_i$。
输出格式
一行一个整数,表示答案。
样例
样例输入:
3 2 100
3 1 2
样例输出:
8
数据范围与提示
样例解释:
如下集中方法满足条件:
$1.121|1|12$
$2.121|1|21$
$3.121|2|12$
$4.121|2|21$
$5.212|1|12$
$6.212|1|21$
$7.212|2|12$
$8.212|2|21$
数据范围:
记$S=\sum \limits_{i=1}^n a_i$。
对于$20\%$的数据,$1\leqslant m\leqslant 3,S\leqslant 10$。
对于$50\%$的数据,$1\leqslant 1,000,1\leqslant m\leqslant 10$。
对于$100\%$的数据,$1\leqslant n\leqslant {10}^6,1\leqslant m\leqslant {10}^6,1\leqslant a_i\leqslant 5,000,S\leqslant {10}^7,2\leqslant p\leqslant {10}^9$。
题解
考虑$DP$。
定义$dp[i][j]$表示到了第$i$层,放了$j$个颜色的装饰品的方案数。
定义$g[i][j]$表示对于一行,到了第$i$个位置,放了$j$个颜色的装饰品的方案数。
我们可以先不管都选了那种颜色,最后在乘上一个组合数就好了。
因为总颜色数是不变的,这样就方便了许多。
$g$数组的转移:
$g[i][j]=g[i-1][j-1]*j+g[i-1][j]*(j-1)$。
$dp$数组的转移:
$dp[i][j]=dp[i-1][0]*g[a[i]][j]*C[j]-dp[i-1][j]*g[a[i]][j]$
$dp[i][0]=dp[i][0]+dp[i][j]$
$dp$数组第一维滚动即可。
时间复杂度:$\Theta(S)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int n,m,p;
int a[1000001],maxn,pri[1000001],t[1000001];
bool vis[10000001],pos;
long long dp[2][5001],g[5001][5001],C[5001];
int main()
{
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
maxn=max(maxn,a[i]);
}
for(int i=2;i<=m;i++)
{
if(!vis[i])pri[++pri[0]]=i;
for(int j=1;j<=pri[0];j++)
{
if(i*pri[j]>m)break;
vis[i*pri[j]]=1;
if(!(i%pri[j]))break;
}
}
dp[0][0]=g[0][0]=1;
for(int i=1;i<=maxn;i++)
for(int j=1;j<=min(m,maxn);j++)
g[i][j]=(g[i-1][j-1]*j%p+g[i-1][j]*(j-1)%p)%p;
for(int i=1;i<=min(m,maxn);i++)
{
int flag1=i,flag2=m-i+1;
for(int j=1;j<=pri[0]&&pri[j]<=flag1;j++)
while(!(flag1%pri[j]))
{
flag1/=pri[j];
t[j]--;
}
for(int j=1;j<=pri[0]&&pri[j]<=flag2;j++)
while(!(flag2%pri[j]))
{
flag2/=pri[j];
t[j]++;
}
C[i]=1;
for(int j=1;j<=pri[0]&&pri[j]<=m;j++)
for(int k=1;k<=t[j];k++)
C[i]=(C[i]*pri[j])%p;
}
for(int i=1;i<=n;i++)
{
pos^=1;
memset(dp[pos],0,sizeof(dp[pos]));
for(int j=1;j<=min(m,a[i]);j++)
{
dp[pos][j]=(dp[pos^1][0]*g[a[i]][j]%p*C[j]%p-dp[pos^1][j]*g[a[i]][j]%p+p)%p;
dp[pos][0]=(dp[pos][0]+dp[pos][j])%p;
}
}
printf("%lld",dp[pos][0]);
return 0;
}
rp++
[CSP-S模拟测试]:长寿花(DP+组合数)的更多相关文章
- [CSP-S模拟测试]:matrix(DP)
题目描述 求出满足以下条件的$n\times m$的$01$矩阵个数:(1)第$i$行第$1~l_i$列恰好有$1$个$1$.(2)第$i$行第$r_i~m$列恰好有$1$个$1$.(3)每列至多有$ ...
- [CSP-S模拟测试]:tree(DP)
题目传送门(内部题57) 输入格式 第一行包含一个数:$n$表示树的节点数.接下来$n-1$行,每行包含两个数:$u,v$表示无根树的一条边. 输出格式 输出$n$行,第$i$行包含一个浮点数,保留三 ...
- [CSP-S模拟测试]:B(DP+数学)
题目传送门(内部题45) 输入格式 第一行$3$个整数$n,m,P$.第二行$m$个整数,表示$m$次询问. 输出格式 一行$m$个整数表示答案. 样例 样例输入1: 2 4 40 1 2 3 样例输 ...
- [CSP-S模拟测试]:蛇(DP+构造+哈希)
题目传送门(内部题140) 输入格式 前两行有两个长度相同的字符串,描述林先森花园上的字母. 第三行一个字符串$S$. 输出格式 输出一行一个整数,表示有多少种可能的蛇,对$10^9+7$取模. 样例 ...
- [CSP-S模拟测试]:最小值(DP+乱搞)
题目背景 $Maxtir$更喜欢序列的最小值. 题目传送门(内部题128) 输入格式 第一行输入一个正整数$n$和四个整数$A,B,C,D$. 第二行输入$n$个整数,第$i$个数表示$a_i$. 输 ...
- [CSP-S模拟测试]:计数(DP+记忆化搜索)
题目描述 既然是萌萌哒$visit\text{_}world$的比赛,那必然会有一道计数题啦!考虑一个$N$个节点的二叉树,它的节点被标上了$1\sim N$的编号.并且,编号为$i$的节点在二叉树的 ...
- [CSP-S模拟测试]:题(DP+数学)
题目描述 出个题就好了.这就是出题人没有写题目背景的原因.你在平面直角坐标系上.你一开始位于$(0,0)$.每次可以在上/下/左/右四个方向中选一个走一步.即:从$(x,y)$走到$(x,y+1),( ...
- [CSP-S模拟测试]:题(DP)
题目描述 由于出题人赶时间所以没办法编故事来作为背景.一开始有$n$个苹果,$m$个人依次来吃苹果,第$i$个人会尝试吃$u_i$或$v_i$号苹果,具体来说分三种情况.$\bullet 1.$两个苹 ...
- [CSP-S模拟测试]:y(DP+bitset)
题目背景 $\frac{1}{4}$遇到了一道水题,叕完全不会做,于是去请教小$D$.小$D$懒得理$\frac{1}{4}$,直接就离开了.于是,$\frac{1}{4}$只好来问你,这道题是这样的 ...
随机推荐
- ajax总结及案例
一.实验简介 目的:检验输入登录名在数据库中是否存在,如果存在,当鼠标移出登录名框后,会提示用户名已存在,并且鼠标指针自动回到登录名框内. 操作步骤: 1.获取登录名的值 2.根据获取的登录名,组织查 ...
- Netty内存管理器ByteBufAllocator及内存分配
ByteBufAllocator 内存管理器: Netty 中内存分配有一个最顶层的抽象就是ByteBufAllocator,负责分配所有ByteBuf 类型的内存.功能其实不是很多,主要有以下几个重 ...
- hdu1423 最长公共上升子序列
题目传送门 Greatest Common Increasing Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- P2579 [ZJOI2005]沼泽鳄鱼(矩乘)
P2579 [ZJOI2005]沼泽鳄鱼 没有食人鱼:直接矩乘优化 有食人鱼:食人鱼周期2.3.4,公倍数12,可以以12为一个周期矩乘,剩下的暴力 注意矩乘不满足乘法交换律,一定要注意乘的顺序 #i ...
- mysql处理重复数据仅保留一条记录
目的:去除(或删除)一个表里面手机号重复的数据,但是需要保留其中一个记录,换句话说,表里面手机号不为空的数据,一个手机有且只有一条记录 表结构: CREATE TABLE `account` ( `i ...
- JVM(12)之 可视化分析工具
开发十年,就只剩下这套架构体系了! >>> 经过前几篇博文对堆内存以及垃圾收集机制的学习,相信小伙伴们已经建立了一套比较完整的理论体系!本篇博客就根据已有的理论知识,通过可视化工 ...
- 大数据-hadoop学习记录
hadoop 创始人 DogCutting 高效,可扩展性,高容错性,价格低廉的大数据软件处理架构 主要应用于数据分析.数据实时查询.数据挖掘领域 HDFS(HadoopDistributeFileS ...
- 第五节:从一条记录说起——InnoDB记录结构
<MySQL 是怎样运行的:从根儿上理解 MySQL>第五节:从一条记录说起——InnoDB记录结构 准备工作 现在只知道客户端发送请求并等待服务器返回结果. MySQL什么方式来访 ...
- 【LeetCode】BFS(共43题)
[101]Symmetric Tree 判断一棵树是不是对称. 题解:直接递归判断了,感觉和bfs没有什么强联系,当然如果你一定要用queue改写的话,勉强也能算bfs. // 这个题目的重点是 比较 ...
- Sass--调用混合宏
在 Sass 中通过 @mixin 关键词声明了一个混合宏,那么在实际调用中,其匹配了一个关键词“@include”来调用声明好的混合宏.例如在你的样式中定义了一个圆角的混合宏“border-radi ...