BZOJ_2111_[ZJOI2010]Perm 排列计数_树形DP+组合数学
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是一个质数。
令fa[i]=i/2,就出现了一棵树。
f[i]表示i的子树的排列方案数。
siz[i]表示i的子树大小。
f[x]*=f[to[i]]*C(siz[x]-1,siz[to[i]])。siz[x]是不断更新的。
其中那个组合数的含义是每个儿子交错排列的方案数。
有坑点,mod可能小于n。逆元需要分类讨论。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1000050
typedef long long ll;
ll fac[N],inv[N],f[N];
int siz[N],n,m,mod;
int head[N],to[N<<1],nxt[N<<1],cnt;
inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
ll qp(ll x,int y) {ll re=1; for(;y;y>>=1,x=x*x%mod) if(y&1) re=re*x%mod; return re;}
void init() {
int i;
for(fac[0]=1,i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
if(mod<=n) {
inv[mod-1]=mod-1;
for(i=mod-2;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;
for(i=mod;i<=n;i++) inv[i]=inv[i%mod];
}else {
inv[n]=qp(fac[n],mod-2);
for(i=n-1;i>=0;i--) inv[i]=inv[i+1]*(i+1)%mod;
}
}
ll C(int x,int y) {
if(x<y) return 0;
if(x<mod&&y<mod)
return fac[x]*inv[y]%mod*inv[x-y]%mod;
return C(x%mod,y%mod)*C(x/mod,y/mod)%mod;
}
void dfs(int x) {
int i;
f[x]=1;
siz[x]=1;
for(i=head[x];i;i=nxt[i]) {
dfs(to[i]);
siz[x]+=siz[to[i]];
f[x]=f[x]*C(siz[x]-1,siz[to[i]])%mod*f[to[i]]%mod;
}
}
int main() {
scanf("%d%d",&n,&mod);
init();
int i;
for(i=2;i<=n;i++) add(i>>1,i);
dfs(1);
printf("%lld\n",f[1]);
}
BZOJ_2111_[ZJOI2010]Perm 排列计数_树形DP+组合数学的更多相关文章
- 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} ...
- 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 ...
- bzoj 2111: [ZJOI2010]Perm 排列计数 (dp+卢卡斯定理)
bzoj 2111: [ZJOI2010]Perm 排列计数 1 ≤ N ≤ 10^6, P≤ 10^9 题意:求1~N的排列有多少种小根堆 1: #include<cstdio> 2: ...
- BZOJ 2111: [ZJOI2010]Perm 排列计数 [Lucas定理]
2111: [ZJOI2010]Perm 排列计数 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 1936 Solved: 477[Submit][ ...
- 2111: [ZJOI2010]Perm 排列计数
2111: [ZJOI2010]Perm 排列计数 链接 题意: 称一个1,2,...,N的排列$P_1,P_2...,P_n$是Magic的,当且仅当$2<=i<=N$时,$P_i> ...
- BZOJ_1833_[ZJOI2010]count 数字计数_数位DP
BZOJ_1833_[ZJOI2010]count 数字计数_数位DP 题意: 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 分析: 数位DP f[i][ ...
- 【BZOJ2111】[ZJOI2010]Perm 排列计数 组合数
[BZOJ2111][ZJOI2010]Perm 排列计数 Description 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi> ...
- [BZOJ2111]:[ZJOI2010]Perm 排列计数(组合数学)
题目传送门 题目描述 称一个1,2,...,N的排列${P}_{1}$,${P}_{2}$,...,${P}_{N}$是Magic的,当且仅当2≤i≤N时,${P}_{i}$>${P}_{\fr ...
- 【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是素数 ...
随机推荐
- 阿里云官方教程 Linux 系统挂载数据盘
适用系统:Linux(Redhat , CentOS,Debian,Ubuntu) * Linux的云服务器数据盘未做分区和格式化,可以根据以下步骤进行分区以及格式化操作. 下面的操作将会把数据盘划 ...
- Ubuntu下配置Nginx HTTPS
HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版.即HTTP下加入S ...
- POJ 2253 Frogger(最小最大距离)
题意 给你n个点的坐标 求第1个点到第2个点的全部路径中两点间最大距离的最小值 非常水的floyd咯 #include<cstdio> #include<cmath> #i ...
- Npm 被公司墙解决方法
npm被公司墙了,不能用npm安装任何包应用了. npm ERR! Darwin npm ERR! argv "/usr/local/Cellar/node/6.4.0/bin/node&q ...
- 【Caffe】源码解析----caffe.proto (转载)
分析caffe源码,看首先看caffe.proto,是明智的选择.好吧,我不是创造者,只是搬运工. 原文地址:http://blog.csdn.net/qq_16055159/article/deta ...
- 【TensorFlow-windows】(七) CNN之VGG-net的测试
主要内容: 1.CNN之VGG-net的测试 2.该实现中的函数总结 平台: 1.windows 10 64位 2.Anaconda3-4.2.0-Windows-x86_64.exe (当时TF还不 ...
- 【转】Android7.0版本以上的手机Eclipse无法打出LogCat
本来想用Eclipse连下手机看下log的,结果LogCat没打出来任何信息,起初怀疑是我的DDMS有问题,结果连了下我老大的手机,完美打出log,看了下Android系统,老大的是6.0的,我的7. ...
- ES通过API调整设置
1.查询es的设置信息 2.查询单个索引的设置 3.设置复制集为0
- Swift 学习笔记 (解决Swift闭包中循环引用的三种方法)
话不多说 直接上代码 class SmartAirConditioner { var temperature:Int = //类引用了函数 var temperatureChange:((Int)-& ...
- 【shell】判断一个变量是否为空
#!/bin/bash argv=" if [ -z "$argv" ] then echo "argv is empty" else echo &q ...