BZOJ.2111.[ZJOI2010]排列计数(DP Lucas)
对于\(a_i>a_{i/2}\),我们能想到小根堆。题意就是,求构成大小为\(n\)的小根堆有多少种方案。
考虑DP,\(f[i]\)表示构成大小为\(i\)的小根堆的方案数,那么如果我们确定左右子树\(size\),则左右子树又分别是一个子问题。
那么可以得到转移方程:\(f[i]=C_{i-1}^l*f[l]*f[r]\)。
因为是按顺序填满二叉树的每一层,所以左子树大小是确定的啊。
\(P\)给定,可能\(\leq n\),所以要用Lucas定理求组合数。
//12540kb 536ms(不知道为什么慢...)
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
const int N=1e6+5;
int f[N],fac[N],inv[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline int FP(int x,int k,int P)
{
int t=1;
for(; k; k>>=1,x=1ll*x*x%P)
if(k&1) t=1ll*t*x%P;
return t;
}
int Calc(int n,int m,int P)
{
if(n<m) return 0;
return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;
}
int C(int n,int m,int P)
{
int res=1;
for(; n&&m; n/=P,m/=P)
res=1ll*res*Calc(n%P,m%P,P)%P;
return res;
}
int main()
{
int n=read(), P=read();
int lim=std::min(n,P-1);
fac[0]=1;
for(int i=1; i<=lim; ++i) fac[i]=1ll*fac[i-1]*i%P;
inv[lim]=FP(fac[lim],P-2,P);
for(int i=lim-1; ~i; --i) inv[i]=1ll*inv[i+1]*(i+1)%P;//inv[0]!
f[1]=f[2]=1, f[3]=2;
for(int i=4,l=1,now=2,mx=3,lim=1; i<=n; ++i)
{
if(mx<i) lim+=now, mx+=(now<<=1);
if(l<lim) ++l;
f[i]=1ll*C(i-1,l,P)*f[l]%P*f[i-1-l]%P;
}
printf("%d\n",f[n]);
return 0;
}
BZOJ.2111.[ZJOI2010]排列计数(DP Lucas)的更多相关文章
- 【bzoj2111】[ZJOI2010]Perm 排列计数 dp+Lucas定理
题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Mogic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Mogic的,答案可能很 ...
- bzoj 2111: [ZJOI2010]Perm 排列计数 (dp+卢卡斯定理)
bzoj 2111: [ZJOI2010]Perm 排列计数 1 ≤ N ≤ 10^6, P≤ 10^9 题意:求1~N的排列有多少种小根堆 1: #include<cstdio> 2: ...
- [ZJOI2010]排列计数 (组合计数/dp)
[ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...
- 洛谷 P2606 [ZJOI2010]排列计数 解题报告
P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...
- 【BZOJ2111】[ZJOI2010]排列计数(组合数学)
[BZOJ2111][ZJOI2010]排列计数(组合数学) 题面 BZOJ 洛谷 题解 就是今年九省联考\(D1T2\)的弱化版? 直接递归组合数算就好了. 注意一下模数可以小于\(n\),所以要存 ...
- P2606 [ZJOI2010]排列计数
P2606 [ZJOI2010]排列计数 因为每个结点至多有一个前驱,所以我们可以发现这是一个二叉树.现在我们要求的就是以1为根的二叉树中,有多少种情况,满足小根堆的性质. 设\(f(i)\)表示以\ ...
- BZOJ 2111: [ZJOI2010]Perm 排列计数 [Lucas定理]
2111: [ZJOI2010]Perm 排列计数 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1936 Solved: 477[Submit][ ...
- BZOJ 4517: [Sdoi2016]排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 911 Solved: 566[Submit][Status ...
- 数学(错排):BZOJ 4517: [Sdoi2016]排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 693 Solved: 434[Submit][Status ...
随机推荐
- openstack项目【day23】:openstack组件介绍
本节内容 openstack介绍 openstack项目(服务名是项目名的别名) openstack运行流程 openstack各组件详解 一:openstack介绍 open ...
- 鸟哥的Linux私房菜——第十七章:Linux 账号与身份管理
视频链接:http://www.bilibili.com/video/av10669732/ 1. Linux 的账号与群组1.1 使用者识别: UID 与 GID1.2 使用者账号:/etc/pas ...
- 鸟哥的Linux私房菜——第十三章:Vim编译器
视频链接: 土豆: B站:http://www.bilibili.com/video/av9891085/ 本章的细节还是挺多的,可是我懒啊~~
- Linux - 用户操作
常用命令 users # 显示所有的登录用户 groups # 列出当前用户和他所属的组 who -q # 显示所有的登录用户 groupadd # 添加组 useradd user # 建立用户 p ...
- MySQL-数据操作-增删改查
1.增加: insert into 表 (列名,列名...) values (值,值,值...) insert into 表 (列名,列名...) values (值,值,值...),(值,值,值.. ...
- ipython的%matplotlib inline如何改写在Python
ipython notebook中有一个相当方便的语句: %matplotlib inline,可以实现运行cell即出现结果图像.但是如果想写在Python程序内,貌似直接%matplotlib i ...
- Insert Interval & Merge Intervals
Insert Intervals Given a non-overlapping interval list which is sorted by start point. Insert a new ...
- 点击超链接打开本地QQ
2014年6月4日 10:20:18 张志斌 这个功能实际上是属于腾讯的推广项目"一键加群"功能: http://qun.qq.com/join.html 用户必须有自己的群,登录 ...
- poj2054
题意:给定一棵树,每个节点有一个权值,现要求给这些节点进行排列,设排列后的节点顺序为v1~vn,它们的权值是w1~wn,那么我们要求一种排列使得w1*1+w2*2+...+wn*n最小.还有一个限制就 ...
- Android实现手机摄像头的自动对焦
如何实现Android相机的自动对焦,而且是连续自动对焦的.当然直接调用系统相机就不用说了,那个很简单的.下面我们主要来看看如如何自己实现一个相机,并且实现自动连续对焦. 代码如下: public c ...