博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BZOJ 2111][ZJOI2010]Perm 排列计数(Lucas定理)
阅读量:4664 次
发布时间:2019-06-09

本文共 1049 字,大约阅读时间需要 3 分钟。

Description

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

Solution

可以先发现这个排列其实是一个小根堆

F[i]=C(siz[i]-1,siz[i<<1])*F[i<<1]*F[i<<1|1]

组合数的部分可以用Lucas解决

#include
#include
#include
#include
#define MAXN 1000005using namespace std;typedef long long LL;int n,P,siz[MAXN],f[MAXN];LL inv[MAXN],fac[MAXN];void init(){ fac[0]=1,inv[1]=1; for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%P; for(int i=2;i<=n;i++) inv[i]=inv[P%i]*(P-P/i)%P; inv[0]=1; for(int i=1;i<=n;i++) inv[i]=inv[i-1]*inv[i]%P;}void dfs(int x){ siz[x]=1; if((x<<1)<=n)dfs(x<<1),siz[x]+=siz[x<<1]; if((x<<1|1)<=n)dfs(x<<1|1),siz[x]+=siz[x<<1|1];}LL C(LL x,LL y){ if(x
n||(x<<1|1)>n)return 1; return ((C(siz[x]-1,siz[x<<1])*solve(x<<1))%P*solve(x<<1|1))%P;}int main(){ scanf("%d%d",&n,&P); init(),dfs(1); printf("%d\n",solve(1)); return 0;}

 

转载于:https://www.cnblogs.com/Zars19/p/7002034.html

你可能感兴趣的文章
android 对软键盘显示和消失,EditView的焦点获取事件进行监听
查看>>
BP(商业计划书写)
查看>>
rancher导入k8s集群后添加监控无数据
查看>>
如何隐藏input边框,使其不显示
查看>>
js 闭包
查看>>
OpenShift
查看>>
Ajax的js库分析简化版
查看>>
新看到的几个新知识点记录
查看>>
编程的最低境界——徒手写排序算法
查看>>
洛谷P1525关押罪犯
查看>>
迷宫问题
查看>>
plt.scatter(X[0, :], X[1, :], c=Y, s=40, cmap=plt.cm.Spectral)出错
查看>>
整数变量运算
查看>>
width这样读取出来是一个字符串,并且带有单位,但是offsetwidth返回的是一个数值。...
查看>>
QT信号和槽
查看>>
转换汉字为字符原始码 如:汉字 -> &#27721;
查看>>
neo4j-jersey分嵌入式和服务式连接图形数据库
查看>>
Java -- Properties类使用 读取配置文档
查看>>
能量晶石
查看>>
node搭建服务器
查看>>