bzoj2111 [ZJOI2010]排列计数
Description
称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大,只能输出模P以后的值
Input
输入文件的第一行包含两个整数 n和p,含义如上所述。
Output
输出文件中仅包含一个整数,表示计算1,2,⋯, ���的排列中, Magic排列的个数模 p的值。
Sample Input
Sample Output
HINT
100%的数据中,1 ≤ ��� N ≤ 106, P��� ≤ 10^9,p是一个质数。 数据有所加强
正解:树形$dp$+组合数学。
$ZJ$水题合集。。
可以发现,这是一棵二叉树(其实就是线段树的结构),$x$的儿子是$x*2$和$x*2+1$。
于是设$f[i]$表示以$i$为根的子树中,以$1$到$size[i]$为排列的合法方案数。
那么转移方程还是很显然的,$f[i]=f[ls[i]]*f[rs[i]]*\binom{sz[i]-1}{sz[ls[i]]}$。
因为$i$上面的数一定是$1$,所以我们可以在$sz[i]-1$个数中任选$sz[ls[i]]$个数到$ls$上,其他数放到$rs$上。
如果$i$只有左儿子,那么$f[i]=f[ls[i]]$;如果$i$是叶子,那么$f[i]=1$。
注意$p$可能比$n$小,所以$\binom{i}{j}$中可能有$p$的倍数,要用$lucas$定理求组合数。
#include <bits/stdc++.h>
#define il inline
#define RG register
#define ll long long
#define N (5000010)
#define ls (x<<1)
#define rs (x<<1|1) using namespace std; int f[N],sz[N],fac[N],ifac[N],inv[N],n,p; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il void pre(){
fac[]=fac[]=ifac[]=ifac[]=inv[]=;
for (RG int i=;i<=n;++i){
inv[i]=1LL*(p-p/i)*inv[p%i]%p;
fac[i]=1LL*fac[i-]*i%p;
ifac[i]=1LL*ifac[i-]*inv[i]%p;
}
return;
} il int c(RG int n,RG int m){
if (n<m) return ;
return 1LL*fac[n]*ifac[m]%p*ifac[n-m]%p;
} il int lucas(RG int n,RG int m){
if (!m) return ; RG int res=c(n%p,m%p);
if (!res) return ;
return 1LL*res*lucas(n/p,m/p);
} il void dfs(RG int x){
if (ls<=n) dfs(ls); if (rs<=n) dfs(rs);
sz[x]=sz[ls]+sz[rs]+;
if (ls>n){ f[x]=; return; }
if (rs>n){ f[x]=f[ls]; return; }
f[x]=1LL*f[ls]*f[rs]%p*lucas(sz[x]-,sz[ls])%p;
return;
} int main(){
#ifndef ONLINE_JUDGE
freopen("perm.in","r",stdin);
freopen("perm.out","w",stdout);
#endif
n=gi(),p=gi(),pre(),dfs();
cout<<f[]; return ;
}
bzoj2111 [ZJOI2010]排列计数的更多相关文章
- BZOJ2111 ZJOI2010排列计数
根据Pi>Pi/2可以看出来这是一个二叉树 所以我们可以用树形DP的思想 f[i]=f[i<<1]*f[i<<1|1]*C(s[i]-1,s[i<<1]),s ...
- 【BZOJ2111】[ZJOI2010]排列计数(组合数学)
[BZOJ2111][ZJOI2010]排列计数(组合数学) 题面 BZOJ 洛谷 题解 就是今年九省联考\(D1T2\)的弱化版? 直接递归组合数算就好了. 注意一下模数可以小于\(n\),所以要存 ...
- [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\) ...
- P2606 [ZJOI2010]排列计数
P2606 [ZJOI2010]排列计数 因为每个结点至多有一个前驱,所以我们可以发现这是一个二叉树.现在我们要求的就是以1为根的二叉树中,有多少种情况,满足小根堆的性质. 设\(f(i)\)表示以\ ...
- BZOJ2111:[ZJOI2010]排列计数——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2111 https://www.luogu.org/problemnew/show/P2606#su ...
- 洛谷P2606 [ZJOI2010]排列计数(组合数 dp)
题意 题目链接 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案 ...
- bzoj2111 Perm 排列计数
称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大,只能输 ...
- [ZJOI2010]排列计数
题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很 ...
随机推荐
- Python Excel操作库
xlrd:支持.xls..xlsx读 xlwt:只支持.xls写 xlutils:只支持.xls读写 依赖于xlrd和xlwt xlwings:支持.xls读,.xlsx读写 可以实现Excel和Py ...
- MySQL Flashback 闪回功能详解
1. 简介 mysqlbinlog flashback(闪回)用于快速恢复由于误操作丢失的数据.在DBA误操作时,可以把数据库恢复到以前某个时间点(或者说某个binlog的某个pos).比如忘了带wh ...
- 聚焦游戏安全,腾讯云GAME-TECH“空降”上海
游戏行业是DDoS攻击高发行业,占DDoS攻击的六成以上,特别是近年来游戏行业的爆发式增长,游戏行业更成为了黑产.外挂.非法信息的聚集地.安全,已然成为游戏行业当前最大的敌人. 6月29日,腾讯云GA ...
- rpm重装python和yum
前些天升级的python, yum就不能用了, 提示 "No module named yum", 然后搜索了一下, 说要重装python和yum, 也没多想, 就按照那些教程去做 ...
- JQuery选择器——《锋利的JQuery》
刚学CSS的时候我们已经接触了选择器,其实就是按照一定的规则选择出来我们想要获取到的元素.在这里,既然选择了用jQuery选择器,首先来谈谈JQuery选择器的优势: 1.简洁的写法:$()函数在很多 ...
- MySQL之基本语句
SQL是Structure Query language(结构化查询语言)的缩写,它是使用关系模型的数据库应用语言.在众多开源数据库中,MySQL正是其中最杰出的代表,MySQL是由三个瑞典人于20世 ...
- jqGrid -treeGrid 按需加载
Load Rows On Demand (AJAX) 参考:http://www.guriddo.net/demo/treegridjs/
- json对象字符串互转
json对象字符串互转 1.Node.js中 JSON.parse(jsonstr); //可以将json字符串转换成json对象 JSON.stringify(jsonobj); //可以将json ...
- python 基础 知识
Python Python 是一种强类型 的解释型 动态型语言Python 对象中的不可变 数字,字符串,元组 ,对于不能改变的会创建一个新的 可变 列表 , 字典 ...
- jQuery之设置元素内容(移动和复制元素,使用append(),appendTo()方法)
jQuery之设置元素内容(移动和复制元素,使用append(),appendTo()方法) ---------- 如果想把内容添加到现有内容末尾,可以利用append()命令.append()命令语 ...