【题目】BZOJ 2111

【题意】求有多少1~n的排列,满足\(A_i>A_{\frac{i}{2}}\),输出对p取模的结果。\(n \leq 10^6,p \leq 10^9\),p是素数。

【算法】计数DP+排列组合+lucas

【题解】令i的父亲为i/2,转化为要求给一棵n个点的完全二叉树编号使得儿子编号>父亲编号。

设\(f[i]\)表示以第i个点为根的子树的编号方案数(1~sz[i]的排列),考虑从两个儿子处转移。

排列的本质是大小关系,所以两个排列组合起来相当于对1sz[i<<1]和1sz[i<<1|1]进行任意组合(各自保持顺序),然后从头到尾重编号成1~sz[i<<1]+sz[i<<1|1]。再将新的编号分配回去。

两个固定排列组合的方案数实际上是将sz[i<<1|1]个“1”分成sz[i<<1]+1份的方案数,采用隔板法易得C(sz[i<<1]+sz[i<<1|1],sz[i<<1]),再枚举两个排列,即:

\[f[i]=f[l_i]*f[r_i]*\binom{sz[i]-1}{sz[l_i]}
\]

为了方便看,这里\(l_i=i<<1\),\(r_i=i<<1|1\)。

由于模数p可能比n小,会导致没有逆元,所以预处理1~min(n,p-1)的阶乘,然后用lucas求解组合数。

复杂度\(O(n)\)。

注意:n较大时线性预处理阶乘逆元保证复杂度,f数组全部初始化为1。

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=2000010;//
int n,MOD,fac[maxn],fav[maxn],sz[maxn],f[maxn];
void gcd(int a,int b,int &x,int &y){if(!b){x=1;y=0;}else{gcd(b,a%b,y,x);y-=x*(a/b);}}
int inv(int a){int x,y;gcd(a,MOD,x,y);return (x%MOD+MOD)%MOD;}
int c(int n,int m){return 1ll*fac[n]*fav[m]%MOD*fav[n-m]%MOD;}
int lucas(int n,int m){
if(n<0||m<0||n<m)return 0;
if(n<MOD)return c(n,m);
return 1ll*c(n%MOD,m%MOD)*lucas(n/MOD,m/MOD)%MOD;
}
int main(){
scanf("%d%d",&n,&MOD);int mx=min(MOD-1,n);
fac[0]=1;for(int i=1;i<=mx;i++)fac[i]=1ll*fac[i-1]*i%MOD;
fav[mx]=inv(fac[mx]);for(int i=mx;i>=1;i--)fav[i-1]=1ll*fav[i]*i%MOD;///
for(int i=1;i<=(n<<1|1);i++)f[i]=1;
for(int i=n;i>=1;i--){
sz[i]=sz[i<<1]+sz[i<<1|1]+1;
f[i]=1ll*f[i<<1]*f[i<<1|1]%MOD*lucas(sz[i]-1,sz[i<<1])%MOD;//
}
printf("%d",f[1]);
return 0;
}

【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas的更多相关文章

  1. bzoj 2111: [ZJOI2010]Perm 排列计数 (dp+卢卡斯定理)

    bzoj 2111: [ZJOI2010]Perm 排列计数 1 ≤ N ≤ 10^6, P≤ 10^9 题意:求1~N的排列有多少种小根堆 1: #include<cstdio> 2: ...

  2. BZOJ 2111: [ZJOI2010]Perm 排列计数 [Lucas定理]

    2111: [ZJOI2010]Perm 排列计数 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1936  Solved: 477[Submit][ ...

  3. BZOJ 2111 [ZJOI2010]Perm 排列计数:Tree dp + Lucas定理

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2111 题意: 给定n,p,问你有多少个1到n的排列P,对于任意整数i∈[2,n]满足P[i ...

  4. bzoj 2111 [ZJOI2010]Perm 排列计数(DP+lucas定理)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2111 [题意] 给定n,问1..n的排列中有多少个可以构成小根堆. [思路] 设f[i ...

  5. bzoj 2111: [ZJOI2010]Perm 排列计数【树形dp+lucas】

    是我想复杂了 首先发现大于关系构成了一棵二叉树的结构,于是树形dp 设f[i]为i点的方案数,si[i]为i点的子树大小,递推式是\( f[i]=f[i*2]*f[i*2+1]*C_{si[i]-1} ...

  6. bzoj 2111: [ZJOI2010]Perm 排列计数 Lucas

    题意:称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大, ...

  7. bzoj 2111: [ZJOI2010]Perm 排列计数

    神题... 扒自某神犇题解: http://blog.csdn.net/aarongzk/article/details/50655471 #include<bits/stdc++.h> ...

  8. 2111: [ZJOI2010]Perm 排列计数

    2111: [ZJOI2010]Perm 排列计数 链接 题意: 称一个1,2,...,N的排列$P_1,P_2...,P_n$是Magic的,当且仅当$2<=i<=N$时,$P_i> ...

  9. BZOJ.2111.[ZJOI2010]排列计数(DP Lucas)

    题目链接 对于\(a_i>a_{i/2}\),我们能想到小根堆.题意就是,求构成大小为\(n\)的小根堆有多少种方案. 考虑DP,\(f[i]\)表示构成大小为\(i\)的小根堆的方案数,那么如 ...

随机推荐

  1. 升级framework4.0后form认证票据失效的问题

    好久没来了,密码都差点忘了,顺便记录下今天配置环境碰到的小问题 网站使用的form authentication做SSO登录,登录域名使用的framework20配置环境 一个栏目升级为4.0环境后, ...

  2. PAT甲题题解-1036. Boys vs Girls (25)-找最大最小,大水题

    题意:给出n个人的姓名.性别.ID.分数,让你找出其中哪个妹纸分数最高.哪个汉子分数最低.以及他们的差如果没有妹纸或者汉子,则对应输出Absent,差用NA代替. 就是for一遍找最大最小值,水题 # ...

  3. No.1101_第十次团队会议

    今天项目进展很多,大家都在现在的成果而开心,信心高涨,后面的任务的完成也基本都能指日可待.之前团队出现了各种问题,沟通出现了很多障碍,导致各方面受阻.现在大家再面对面坦诚相对,交流了一下自己的想法,结 ...

  4. 【MOOC EXP】Linux内核分析实验一报告

    程涵  原创博客 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  [反汇编一个简单的C程序]   实验 ...

  5. linux内核分析第一周学习笔记

    linux内核分析第一周学习笔记 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.co ...

  6. webSocket开发chat application过程

    本次使用websocket开发chat的功能已经接近尾声,等到压力测试结束之后就可以上线了.在此记录一下整个开发过程. ---------------------------------------- ...

  7. DHCP中续代理

    什么是DHCP中继代理? 答:DCHP中继代理(即DHCP Relay  Agent )用于转发来自于另一个没有DHCP服务器子网段中的客户端的DHCP请求,即当一台DCHP客户机发起请求后,此时DH ...

  8. Linux 基础一(系统分区、格式化与挂载)

    1.Linux 基础之系统分区与格式化 讲分区之前,先说一下硬盘结构:硬盘(机械)的横截面是一个圆,并且被分成等大小的扇区,每个扇区的大小是 512Byte,其中有 446Byte 被用来存储启动信息 ...

  9. BUG报告

    Bug1 1.看到的现象:如果在注册时使用中文作为密码,并不会报错,但是登陆过程中的密码框却不能输入中文导致无法登陆. 2.期待的现象:登陆也能支持中文或在注册功能中添加输入约束. 3.二者的差异 在 ...

  10. Windows 设置开机自动登录

    1. 自己一些windows的虚拟机 有时候开机之后 输入用户名密码时间特别长. 需要等待很久, 如果能够设置开机自动登录的话 能够节约很多时间. 2. 最简单的办法  运行输入 control us ...