题目大意

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

题解

  1. 问题转换,建立模型。

    可以发现,本题就是要求小根完全二叉树的个数。
  2. 树上dp

    定义f[n]为以n为根的完全二叉树个数。

    根据乘法原理,

    f[n] = f[i<<1] * f[i<<1|1] * C(s[i]-1, i << 1)

    可以知道,n可以从后向前递推。

代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e6+5;
#define ll long long
int n, p;
int f[maxn], s[maxn];
int fact[maxn], ifact[maxn];
int pow(int a, int b, int p) {
int ans = 1;
while(b) {
if(b & 1) ans = (ll) ans * a % p;
b >>= 1;
a = (ll)a * a %p;
}
return ans;
}
int inv(int n, int p) {
return pow(n, p-2, p);
}
void init() {
fact[1] = 1;
ifact[1] = 1;
for(int i = 2; i <= n; i++) {
fact[i] = (ll)i * fact[i-1] % p;
ifact[i] = inv(fact[i], p);
}
}
int C(int n, int m, int p) {
if(n < m) return 0;
return (ll)fact[n] * ifact[m] % p * ifact[n-m] % p;
}
int lucas(int n, int m, int p) {
if(!n && !m) return 1;
return (ll)C(n%p, m%p, p) * lucas(n/p, m/p, p) % p;
}
int main() {
ifact[0] = 1;
scanf("%d %d", &n, &p);
init();
for(int i = n; i; i--) {
s[i] = s[i<<1] + s[i << 1|1] + 1;
f[i] = lucas(s[i]-1, s[i<<1], p);
if(i << 1 <= n) f[i] = (ll)f[i] * f[i<<1] % p;
if((i << 1 | 1) <= n) f[i] = (ll)f[i] * f[i<<1|1] % p;
}
printf("%d", f[1]);
}

[bzoj2111][ZJOI2010]Perm 排列计数 ——问题转换,建立数学模型的更多相关文章

  1. BZOJ2111: [ZJOI2010]Perm 排列计数

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2111 题意:一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2< ...

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

    题意就是求一个n个点的堆的合法形态数. 显然,给定堆中所有数的集合,则这个堆的根是确定的,而由于堆是完全二叉树,所以每个点左右子树的大小也是确定的. 设以i为根的堆的形态数为F(i),所以F(i)+= ...

  3. [BZOJ2111]:[ZJOI2010]Perm 排列计数(组合数学)

    题目传送门 题目描述 称一个1,2,...,N的排列${P}_{1}$,${P}_{2}$,...,${P}_{N}$是Magic的,当且仅当2≤i≤N时,${P}_{i}$>${P}_{\fr ...

  4. 【BZOJ2111】[ZJOI2010]Perm 排列计数 组合数

    [BZOJ2111][ZJOI2010]Perm 排列计数 Description 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi> ...

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

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

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

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

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

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

  8. 【bzoj2111】[ZJOI2010]Perm 排列计数 dp+Lucas定理

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

  9. 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas

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

随机推荐

  1. Django+vue在腾讯云上搭建前后端分离项目

    最近打算用Django+vue搭建一个个人主站,在此记录一下搭建项目的整个过程. 一 开发环境: 腾讯云Centos     7 Python                3.7 Django    ...

  2. C语言数组篇(二)指针数组和数组指针

    数组指针 和 指针数组         这两个名词可以说是经常搞混了         数组指针--> 数组的指针       就是前面讲的 指向数组a的指针p;         指针数组--&g ...

  3. 我教你怎么玩转git

    我教你怎么玩转git 1.想要练习解决冲突? 很好办.创建本地分支,a,b, a上面,这样改.b上面那样改. 然后你就解决冲突就可以了. 可以merge 或者cheerypick 2.想要玩一个不要历 ...

  4. interface in iOS

    lo = localhosten = ethernetap = Probably for access point (if you are acting as a wifi host) pdp_ip ...

  5. CentOS 更换yum源为aliyun yum源

    CentOS自带的yum源为官方的源,由于墙的原因,经常无法访问,国内也有不错的源,这里讲一下使用aliyun的源替换原yam源. 第一种方法 1.安装base reop源 cd /etc/yum.r ...

  6. Eclipse 菜单---Eclipse教程第04课

    Eclipse 查看的菜单栏通常包含以下几个菜单: File 菜单 Edit 菜单 Navigate 菜单 Search 菜单 Project 菜单 Run 菜单 Window 菜单 Help 菜单 ...

  7. unbantu安装wmvare

    最新评论 wsmyyjie:写的太好了!!! zhangmin92:回复 wopapa523: 这个是你用另一.. wopapa523:请问i11是在哪里输入的? myh65013:挺深入的 andk ...

  8. 创建、导入、导出、复制以及粘贴 WMI 筛选器

    TechNet 库 Deployment Forefront Identity and Access Management 基础结构优化 浏览器 Microsoft Dynamics Products ...

  9. Jmeter 场景设计

    今天的业务场景是: 1.管理员登录后台---登录成功后添加一个某类型的产品---产品添加成功后,再为该产品添加10个排期. 2.管理员登录后台--登录成功后添加多个不同类型产品---产品全部添加完成后 ...

  10. DDT驱动

    下载ddt并安装 Pip install ddt 或者官网下载安装 http://ddt.readthedocs.io/en/latest/ https://github.com/txels/ddt ...