P2606 [ZJOI2010]排列计数

因为每个结点至多有一个前驱,所以我们可以发现这是一个二叉树。现在我们要求的就是以1为根的二叉树中,有多少种情况,满足小根堆的性质。

设\(f(i)\)表示以\(i\)为根的子树中满足小根堆性质的情况,那么就有:\(f(i)=f(ls)*f(rs)*C_{sum(i)-1}^{sum(ls)}\)。表示选出\(sum(ls)\)个结点来作为左儿子中的结点,并且左右儿子都满足小根堆的性质。这里左右儿子这两个问题都是独立的,所以可以直接运用乘法原理。

这里求组合数可以直接用Lucas定理来求,Lucas定理为:若p是一个质数,那么\(C_n^m=C_{\frac{n}{p}}^{\frac{m}{p}}*C_{n\mod p}^{m\mod p}\mod p\)。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll ;
const int N = 2e6 + 5;
ll n, p;
ll inv[N], fac[N], s[N], f[N];
ll C(ll a, ll b) {
if(a < b) return 0;
if(a == b || b == 0) return 1;
if(a < p && b < p) return inv[b] * inv[a - b] % p * fac[a] % p;
return C(a % p, b % p) * C(a / p, b / p) % p;
}
ll qp(ll a, ll b) {
ll ans = 1;
while(b) {
if(b & 1) ans = ans * a % p;
a = a * a % p;
b >>= 1;
}
return ans ;
}
int main() {
cin >> n >> p;
fac[0] = 1;
for(int i = 1; i <= n; i++) fac[i] = 1ll * fac[i - 1] * i % p;
for(int i = 1; i <= n; i++) inv[i] = qp(fac[i], p - 2) ;
for(int i = 1; i <= n; i++) s[i] = 1;
for(int i = n; i >= 2; i--) s[i >> 1] += s[i] ;
for(int i = n; i >= 1; i--) {
int ls = i << 1, rs = i << 1 | 1;
if(f[ls] && f[rs]) f[i] = f[ls] * f[rs] % p * C(s[i] - 1, s[ls]) % p;
else if(f[ls]) f[i] = f[ls] ;
else f[i] = 1;
}
cout << f[1] ;
return 0;
}

P2606 [ZJOI2010]排列计数的更多相关文章

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

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

  2. ●洛谷P2606 [ZJOI2010]排列计数

    题链: https://www.luogu.org/problemnew/show/P2606题解: 组合数(DP),Lucas定理 首先应该容易看出,这个排列其实是一个小顶堆. 然后我们可以考虑dp ...

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

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

  4. 洛谷P2606 [ZJOI2010]排列计数

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

  5. 洛谷P2606 [ZJOI2010]排列计数(数位dp)

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

  6. 洛谷P2606 [ZJOI2010]排列计数 组合数学+DP

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

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

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

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

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

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

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

随机推荐

  1. Spring Boot JDBC:加载DataSource过程的源码分析及yml中DataSource的配置

    装载至:https://www.cnblogs.com/storml/p/8611388.html Spring Boot实现了自动加载DataSource及相关配置.当然,使用时加上@EnableA ...

  2. [数据结构 - 第6章] 树之链式二叉树(C语言实现)

    一.什么是二叉树? 1.1 定义 二叉树,是度为二的树,二叉树的每一个节点最多只有二个子节点,且两个子节点有序. 1.2 二叉树的重要特性 (1)二叉树的第 i 层上节点数最多为 2n-1: (2)高 ...

  3. perl修改镜像源地址

    perl修改源地址 这里推荐中科大的源 http://mirrors.ustc.edu.cn/CPAN/ perl -MCPAN -e shell 1.执行cpan命令确认存在该命令 如果cpan执行 ...

  4. 一致性hash算法应用场景、详解与实现(JAVA)

    一.概述 在分布式环境下,开发者通常会遇到一些分布存储的场景,例如数据库的分库分表(比如用户id尾号为1的放入数据库1,id尾号为2的放入数据库2):又如分布式缓存数据的获取(比如根据ip地址进行缓存 ...

  5. 【笔试题】Overriding in Java

    笔试题 Overriding in Java Question 1 以下程序的输出结果为( ). class Derived { protected final void getDetails() { ...

  6. 更改ubuntu桌面环境

    1.修改桌面环境 update-alternatives --config x-session-manager 2.卸载某一种ppa源下面的软件 sudo apt-get install ppa-pu ...

  7. java中通过Adb判断PC是否连接了移动设备

    最近用到PC端和移动端通过USB连接传输数据的方式,于是总在使用Adb命令,为了逻辑的严谨和代码容错,想在传输数据的之前,PC和移动端先建立一次会话,防止移动端还未连接就直接传输数据会报错,找了很久并 ...

  8. C++实现 企业信息管理系统

    2.1总体需求 ​ 2.2管理需求 ​ ​ 3.总体架构 ​ 由于代码量比较大,请移步GitHub或码云 码云:传送门 , GitHub:传送门 话不多说,直接上效果 我是在Linux Ubuntu1 ...

  9. 5. Spark Streaming高级解析

    5.1 DStreamGraph对象分析 在Spark Streaming中,DStreamGraph是一个非常重要的组件,主要用来: 1. 通过成员inputStreams持有Spark Strea ...

  10. golang --Converting and Checking Types

    package main import ( "fmt" "strconv" ) func main() { strVar := "100" ...