[ZJOI2010]Perm
[ZJOI2010]Perm
题目
称一个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
20 23
OUTPUT
16
解题报告
这竟然是一道树规= =
其实想明白之后挺简单的
我们考虑一颗满二叉树,一个节点$i$如果有左儿子,那么它的左儿子编号一定为$i\times 2$,如果它有右儿子,那么它的右儿子编号一定为$i\times 2+1$
再回来看这道题,假如我们建一颗满二叉树,那么问题不就转化成所有儿子的权值都比父亲的权值大的方案数么?
设$f[size[i]]$代表编号为$i$的节点的方案数
我们要取出$i-1$个(把自己去掉)比它大的数,一部分放在左子树,一部分放在右子树,且当左子树确定了取出哪些数时,右子树所取出的数也是一定的
故我们可以推出状态转移方程:
$$f[size[i]]=C_{size[i]-1}^{size[i<<1]}\times f[size[i<<1]]\times f[size[i<<1|1]]$$
然后实现即可
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long L;
L n,p;
L fac[];
inline L po(L x,L hm){
L ret();
while(hm){
if(hm&)
ret=ret*x%p;
x=x*x%p;
hm>>=;
}
return ret;
}
inline L C(int n,int m){
return fac[n]*po(fac[m],p-)%p*po(fac[n-m],p-)%p;
}
struct edge{
int e;
edge *n;
}a[],*pre[];
int tot;
inline void insert(int s,int e){
a[++tot].e=e;
a[tot].n=pre[s];
pre[s]=&a[tot];
}
int size[];
inline void get_size(int u){
size[u]=;
for(edge *i=pre[u];i;i=i->n){
int e(i->e);
if(!size[e]){
get_size(e);
size[u]+=size[e];
}
}
}
L f[];
inline void dfs(int u){
if(u>n){
// size[u]=0;
// f[0]=1;
return;
}
// cout<<u<<endl;
// size[u]=1;
dfs(u<<);
// size[u]+=size[u<<1];
dfs(u<<|);
// size[u]+=size[u<<1|1];
f[size[u]]=C(size[u]-,size[u<<])*f[size[u<<]]%p*f[size[u<<|]]%p;
}
inline int gg(){
// freopen("permzj.in","r",stdin);
// freopen("permzj.out","w",stdout);
scanf("%lld%lld",&n,&p);
fac[]=fac[]=;
for(int i=;i<=n;++i){
L tmp(i);
while(tmp%p==)
tmp/=p;
fac[i]=fac[i-]*tmp%p;
}
for(int i=;i<=n;++i){
if((i<<)>n)
break;
insert(i,i<<);
if((i<<|)>n)
break;
insert(i,i<<|);
}
get_size();
f[]=f[]=;
dfs();
printf("%lld",f[n]%p);
// for(int i=1;i<=n;++i)
// cout<<"i="<<i<<" size[i]="<<size[i]<<endl;
return ;
}
int K(gg());
int main(){;}
[ZJOI2010]Perm的更多相关文章
- 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 2111: [ZJOI2010]Perm 排列计数 (dp+卢卡斯定理)
bzoj 2111: [ZJOI2010]Perm 排列计数 1 ≤ N ≤ 10^6, P≤ 10^9 题意:求1~N的排列有多少种小根堆 1: #include<cstdio> 2: ...
- 【BZOJ2111】[ZJOI2010]Perm 排列计数 组合数
[BZOJ2111][ZJOI2010]Perm 排列计数 Description 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi> ...
- BZOJ2111: [ZJOI2010]Perm 排列计数
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2111 题意:一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2< ...
- 【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是素数 ...
- bzoj 2111 [ZJOI2010]Perm 排列计数(DP+lucas定理)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2111 [题意] 给定n,问1..n的排列中有多少个可以构成小根堆. [思路] 设f[i ...
- [BZOJ2111][ZJOI2010]Perm排列计数(组合数学)
题意就是求一个n个点的堆的合法形态数. 显然,给定堆中所有数的集合,则这个堆的根是确定的,而由于堆是完全二叉树,所以每个点左右子树的大小也是确定的. 设以i为根的堆的形态数为F(i),所以F(i)+= ...
- 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 ...
随机推荐
- telnet端口问题
今天测试发现telnet 一个端口不通,开始还以为是服务开放这个端口有问题,后来才发现这个端口是udp的.而telnet下层走的tcp协议,自然无法测试那些tcp的端口. 而之前下意识里还总以为都可以 ...
- java enum int String 相互转换
1. enum<->int enum -> int: int i = enumType.value.ordinal(); int -> enum: enumType b= e ...
- P3390矩阵快速幂
题目背景 矩阵快速幂 题目描述 给定n*n的矩阵A,求A^k 输入输出格式 输入格式: 第一行,n,k 第2至n+1行,每行n个数,第i+1行第j个数表示矩阵第i行第j列的元素 输出格式: 输出A^k ...
- [Swift通天遁地]五、高级扩展-(1)快速检测设备属性:版本、类型、屏幕尺寸
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- SpringBoot集成Mybatis配置动态数据源
很多人在项目里边都会用到多个数据源,下面记录一次SpringBoot集成Mybatis配置多数据源的过程. pom.xml <?xml version="1.0" encod ...
- ios-判断手机上是否安装了某个App
方法一 1.获取手机中安装的所有App 1.1.runtime中的方法,所以要导入 #include <objc/runtime.h> 1.2.在 AppDel ...
- Spring Boot (26) RabbitMQ延迟队列
延迟消息就是指当消息被发送以后,并不想让消费者立即拿到消息,而是等待指定时间后,消费者才拿到这个消息进行消费. 延迟队列 订单业务: 在电商/点餐中,都有下单后30分钟内没有付款,就自动取消订单. 短 ...
- 【Spring】IOC
浅谈IOC IOC的理论背景 图1:传统系统中,对象之间相互引用的一幅图,在采用面向对象方法设计的软件系统中,它的底层的实现都是由n个对象所组成的,所有的对象通彼此之间的合作最终实现系统的业务逻辑,如 ...
- Android O Bitmap 内存分配
我们知道,一般认为在Android进程的内存模型中,heap分为两部分,一部分是native heap,一部分是Dalvik heap(实际上也是native heap的一部分). Andro ...
- Android sensor 系统框架 (一)
这几天深入学习了Android sensor框架,以此博客记录和分享分析过程,其中难免会有错误的地方,欢迎指出! 这里主要分析KERNEL->HAL->JNI这3层的流程.主要从以下几方面 ...