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

20 23

Sample Output

16

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]排列计数的更多相关文章

  1. BZOJ2111 ZJOI2010排列计数

    根据Pi>Pi/2可以看出来这是一个二叉树 所以我们可以用树形DP的思想 f[i]=f[i<<1]*f[i<<1|1]*C(s[i]-1,s[i<<1]),s ...

  2. 【BZOJ2111】[ZJOI2010]排列计数(组合数学)

    [BZOJ2111][ZJOI2010]排列计数(组合数学) 题面 BZOJ 洛谷 题解 就是今年九省联考\(D1T2\)的弱化版? 直接递归组合数算就好了. 注意一下模数可以小于\(n\),所以要存 ...

  3. [ZJOI2010]排列计数 (组合计数/dp)

    [ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...

  4. 洛谷 P2606 [ZJOI2010]排列计数 解题报告

    P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...

  5. P2606 [ZJOI2010]排列计数

    P2606 [ZJOI2010]排列计数 因为每个结点至多有一个前驱,所以我们可以发现这是一个二叉树.现在我们要求的就是以1为根的二叉树中,有多少种情况,满足小根堆的性质. 设\(f(i)\)表示以\ ...

  6. BZOJ2111:[ZJOI2010]排列计数——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2111 https://www.luogu.org/problemnew/show/P2606#su ...

  7. 洛谷P2606 [ZJOI2010]排列计数(组合数 dp)

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

  8. bzoj2111 Perm 排列计数

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

  9. [ZJOI2010]排列计数

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

随机推荐

  1. jdk8涉及到的接口、类及方法

    bi是binary的简写,二元的,表示两个参数 unary,一元的,表示一个参数 1.函数式接口Supplier T get(),不接收参数,有返回值 IntSupplier,int getAsInt ...

  2. oracle 基础(一)--闪回技术

    一,闪回表初探 闪回须知: 1 使用闪回表注意如下事项: 2 3 (1)被闪回的表必须启用行移动功能 4 5 SQL> alter table dept enable row movement; ...

  3. es6 vs commonjs

    'use strict' export function showMe() { alert("es6"); }; class logging { constructor() { a ...

  4. ionic 开发当中,有一些常用的方法。

    在开发项目的时候,有些常用的功能封装到一个类里. 以后要用的话,直接导入过来就可以用了,有一些方法是从网站复制过来的,有些方法是网上复制过来,然后自己修改了一下,标记一下吧!   /**      * ...

  5. MVC参数自动装配

    在拿到一个类型的所有属性以及字段的描述信息后,就可以通过循环的方式,根据这些数据成员的名字去QueryString,Form,Session,Cookie读取所需的数据了. 就是遍历参数,然后用反射遍 ...

  6. TOJ 1840 Jack Straws

    Description In the game of Jack Straws, a number of plastic or wooden "straws" are dumped ...

  7. Python编码规范杂记(很乱:))

    Python编码规范 导入模块 每一个(第三方)模块的导入都需要两个import语句, 如下 使用import some的方式导入模块, 如果有还有子模块的话, 则from father.son im ...

  8. json数据的存储与读取

    1.  json数据格式: data = [ {"key1":"xxx","item":"ddd"}, {"k ...

  9. 项目视图 Project Browser

    项目视图 在这个视图,你可以访问.管理你当前项目资源. 项目视图左侧面板显示项目的文件夹结构的分层列表,当从列表中单击一个文件夹,其内容会显示在面板的右边.你可以点击小三角展开或折叠文件夹,显示他包含 ...

  10. .net比较两个时间的大小,不含日期,精确到分

    解决方案: 1.将要比较的两个时间转成DateTime类型: DateTime date1 = DateTime.Parse("8:00"); DateTime date2 = D ...