洛谷 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; ...
随机推荐
- myeclipse从SVN上拉项目,各种报错,jar包没有引入
问:项目中myeclipse从SVN上拉项目,各种报错,jar包没有引入 答: 从SVN拉项目步骤一定不能出错,一有点差异就会出非常多的事情 1-右键项目checkout的时候 第一页选默认值就行 点 ...
- 详解 JavaScript 中 splice() 方法
splice() 方法是一个比较少用的方法,但是功能确实很好,并且在我们 coding 的时候,经常有需要 splice() 方法,先介绍一下该方法. 在 JavaScript 中 splice() ...
- emplace_back
c++11 的 list deque 和 vector 增加了emplace_back函数,相对于push_back函数,它减少了一次类的构造,因此效率更高,推荐使用. #include <li ...
- MongoDb第一天
安装之后进入cmd.进入到安装目录下的bin目录下. 任意选一个空目录,建立db,log的文件夹.之后终端命令行里面输入回车. D:\ProgramFiles\MongoDB\Server\3.6\b ...
- POJ:3977-Subset(双向搜索)
Subset Time Limit: 30000MS Memory Limit: 65536K Total Submissions: 5961 Accepted: 1129 Description G ...
- Aizu:2170-Marked Ancestor
Marked Ancestor Time limit 8000 ms Memory limit 131072 kB Problem Description You are given a tree T ...
- 翻译 | 卷积码的维特比(Viterbi)译码
对维特比译码的接触很早就开始了,也想过要写一篇总结性的文章,但无奈心中一直有几个疑团没能得到合理的解答.比如什么时候开始进行回溯译码比较合适?维特比译码的性能相比分组码等其他编码的译码性能究竟好在哪里 ...
- centos使用--软件启动关闭等操作的命令
关于centos服务的命令经常会遇到这几种 service systemctl /etc/init.d/ 1 service和/etc/init.d/ service是一个脚本命令,分析service ...
- 四大关键步骤掌握CloudOps模型
[TechTarget中国原创] 要让IT运维向云演进,企业必须拥抱自动化,并且改变资源预配的思考方式. 新涌现的术语CloudOps——云运维的简写,指代企业如何运行以及管理基于云的系统.并且,随着 ...
- 数据库路由中间件MyCat - 源代码篇(2)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 2. 前端连接建立与认证 Title:MySql连接建立以及认证过程client->MySql:1.T ...