洛谷 P2606 [ZJOI2010]排列计数 解题报告
P2606 [ZJOI2010]排列计数
题目描述
称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\),有\(P_i>P_{\lfloor i/2 \rfloor}\). 计算\(1,2,...N\)的排列中有多少是\(Magic\)的,答案可能很大,只能输出模\(P\)以后的值
输入输出格式
输入格式:
输入文件的第一行包含两个整数\(n\)和\(p\),含义如上所述。
输出格式:
输出文件中仅包含一个整数,表示计算\(1,2,...,n-1,n\)的排列中, \(Magic\)排列的个数模\(p\)的值。
说明
\(100\%\)的数据中,\(1 \le N \le 10^6\), \(P \le 10^9\),\(p\)是一个质数。
想了好久啊QAQ
发现按照大小关系构成的一个树形结构就是二叉堆
节点编号为位置的小根堆
要给堆的每个节点不重复都放\(1\)~\(n\)的数,问方案数
到这里就比较容易了
\(dp_i=dp_{ls} \times dp_{rs} \times C_{siz_i-1}^{siz_i-1-siz_{ls}}\)
意义也比较明了了
这里要用lucas处理一下,因为\(p\)可能小于\(n\)
然而\(n|p\)时就比较麻烦了,要用扩展\(lucas\)(我太懒了没写,这样只能过洛谷但过不了bzoj
Code:
#include <cstdio>
#define ll long long
#define ls id<<1
#define rs id<<1|1
const int N=1e6+10;
ll n,p,u,fac[N],inv[N];
ll quickpow(ll d,ll k)
{
ll f=1;
while(k)
{
if(k&1) f=f*d%p;
d=d*d%p;
k>>=1;
}
return f;
}
void init()
{
u=(p<n?p:n);
inv[0]=fac[0]=1;
for(ll i=1;i<=u;i++)
fac[i]=fac[i-1]*i%p;
inv[u]=quickpow(fac[u],p-2);
for(ll i=u-1;i;i--)
inv[i]=inv[i+1]*(i+1)%p;
}
ll lucas(ll a,ll b)
{
if(a<b) return 0;
if(a<=u) return fac[a]*inv[b]%p*inv[a-b]%p;
return lucas(a/p,b/p)*lucas(a%p,b%p)%p;
}
ll siz[N<<2];
ll dfs(int id)
{
if(id>n) return 1ll;
siz[id]=1;
ll ans=dfs(ls)*dfs(rs)%p;
siz[id]+=siz[ls]+siz[rs];
return ans*lucas(siz[id]-1,siz[id]-1-siz[ls])%p;
}
int main()
{
scanf("%lld%lld",&n,&p);
init();
printf("%lld\n",dfs(1));
return 0;
}
2018.9.23
洛谷 P2606 [ZJOI2010]排列计数 解题报告的更多相关文章
- ●洛谷P2606 [ZJOI2010]排列计数
题链: https://www.luogu.org/problemnew/show/P2606题解: 组合数(DP),Lucas定理 首先应该容易看出,这个排列其实是一个小顶堆. 然后我们可以考虑dp ...
- 洛谷P2606 [ZJOI2010]排列计数(组合数 dp)
题意 题目链接 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案 ...
- 洛谷P2606 [ZJOI2010]排列计数
题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很 ...
- 洛谷P2606 [ZJOI2010]排列计数(数位dp)
题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很 ...
- 洛谷P2606 [ZJOI2010]排列计数 组合数学+DP
题意:称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有多少是Magic的,答案可能很大, ...
- 洛谷 P1144 最短路计数 解题报告
P1144 最短路计数 题目描述 给出一个\(N\)个顶点\(M\)条边的无向无权图,顶点编号为\(1-N\).问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 第一行包含2个正 ...
- 洛谷 P2604 [ZJOI2010]网络扩容 解题报告
P2604 [ZJOI2010]网络扩容 题目描述 给定一张有向图,每条边都有一个容量C和一个扩容费用W.这里扩容费用是指将容量扩大1所需的费用.求: 1. 在不扩容的情况下,1到N的最大流: 2. ...
- P2606 [ZJOI2010]排列计数
P2606 [ZJOI2010]排列计数 因为每个结点至多有一个前驱,所以我们可以发现这是一个二叉树.现在我们要求的就是以1为根的二叉树中,有多少种情况,满足小根堆的性质. 设\(f(i)\)表示以\ ...
- 洛谷_Cx的故事_解题报告_第四题70
1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h> struct node { long x,y,c; ...
随机推荐
- Oracle字符集的查看查询和Oracle字符集的设置修改(转载)
本文主要讨论以下几个部分:如何查看查询oracle字符集. 修改设置字符集以及常见的Oracle UTF8字符集和Oracle exp 字符集问题. 一.什么是Oracle字符集 Oracle字符集是 ...
- .NET向WebService传值为decimal、double、int、DateTime等非string类型属性时,服务器端接收不到数据的问题
最近在做CRM项目时,使用C#调用SAP PI发布的WebService服务时遇到的问题: 向WebService传值为decimal.double.int.DateTime等非string类型数据时 ...
- SVN中trunk,branches,tags用法详解(转载)
转载出处:http://www.cnblogs.com/dafozhang/archive/2012/06/28/2567769.html Subversion是一个自由开源的版本控制系统.在Subv ...
- IO流的应用_Copy文件
IO流的应用_Copy文件 (1) import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...
- ubuntu16.06+vsftpd+nginx搭建图片服务器
安装vsftpd 注:以下指令都在root账户下操作 # apt安装vsftpd apt-get install vsftpd #启动vsftpd service vsftpd start #新建用户 ...
- Apache POI 工具类 [ PoiUtil ]
pom.xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml ...
- php精华之独孤九剑
首先分享一个地址 https://segmentfault.com/a/1190000013696265(这个是主要的分享,人家作者写的非常棒
- debug注意事项
1 先看关键代码是否正确,然后查一遍是否有变量名打错. 2 再看初始化有没有问题 3 再把范围开大和开int64(这应该刚开始看题就要注意,在不爆内存的情况下开int64) 4 静态调试,输出中间值. ...
- python基础之数据类型与变量patr1
1:编写for循环,利用索引遍历出每一个字符 msg='hello egon 666' 2:编写while循环,利用索引遍历出每一个字符 msg='hello egon 666' 3:msg='hel ...
- 万年历Calendar、js修改日期
//万年历 Calendar cal = Calendar.getInstance(); cal.add(Calendar.DATE,-1); //改变日期,改变年份.月份类似 SimpleDateF ...