[BZOJ2111][ZJOI2010]Perm 排列计数(组合数学+lucas定理)
来源:互联网 发布:cc攻击防御 php 编辑:程序博客网 时间:2024/05/29 15:03
题目描述
传送门
题解
首先第一个位置肯定是1
若把i的两个儿子看做i*2和i*2+1,这样就形成了一颗以1为根的有根树
这棵树的形态是不变的,我们需要做的就是将1-n填到每一个节点里然后保证父亲小于儿子
对于一颗子树,我们考虑怎样选才能满足要求,可以发现由于数是1-n,两两数之间的相对大小是不变的,也就是说,不会出现这棵子树中可以填2,3,4而不能填3,4,5的情况
而假设我们选出了若干数填到这棵子树中,根一定是确定的,也就是这些数中最小的数
那么选数的方案只由子树的大小有关
可以写出递推式f(i)=c(size(i)-1,size(ls(i)))*f(i*2)*f(i*2+1),c是组合数
递归求解即可
不过还有一个问题就是,这里可能n>p导致np不互质,这样求组合数不能直接用逆元,要用lucas定理
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define LL long long#define N 1000005LL n,Mod,ans=1LL;LL size[N+1],mul[N+1];void calc(){ mul[0]=1LL; for (LL i=1;i<=n;++i) mul[i]=mul[i-1]*i%Mod;}void exgcd(LL a,LL b,LL &x,LL &y){ if (!b) x=1LL,y=0LL; else exgcd(b,a%b,y,x),y-=a/b*x;}LL inv(LL A,LL Mod){ LL a=A,b=Mod,x=0LL,y=0LL; exgcd(a,b,x,y); x=(x%b+b)%b; if (!x) x+=b; return x;}LL C(LL n,LL m){ if (m>n) return 0LL; return mul[n]*inv(mul[m]*mul[n-m]%Mod,Mod)%Mod;}LL lucas(int n,int m,int Mod){ LL ans=1LL; for (;m;n/=Mod,m/=Mod) ans=ans*C(n%Mod,m%Mod)%Mod; return ans;}void dfs(LL x){ LL l=0; if (x*2<=n) { dfs(x*2); size[x]+=size[x*2]; l=size[x*2]; } if (x*2+1<=n) { dfs(x*2+1); size[x]+=size[x*2+1]; } ans=ans*lucas(size[x],l,Mod)%Mod; ++size[x];}int main(){ scanf("%lld%lld",&n,&Mod); calc(); dfs(1); printf("%lld\n",ans);}
总结
①遇到求逆元一定要考虑ap是否互质
0 0
- [BZOJ2111][ZJOI2010]Perm 排列计数(组合数学+lucas定理)
- [bzoj2111][ZJOI2010]Perm 排列计数(组合数学)
- BZOJ 2111 ZJOI2010 Perm 排列计数 组合数学+Lucas定理
- BZOJ 2111 ZJOI2010 Perm 排列计数 组合数学+Lucas定理
- 【bzoj2111】【zjoi2010】【perm排列计数】【dp+Lucas定理】
- 【递推+lucas定理】BZOJ2111 [ZJOI2010]Perm 排列计数
- Bzoj2111:[ZJOI2010]Perm 排列计数:树形动态规划+组合数学
- bzoj 2111: [ZJOI2010]Perm 排列计数 (组合数学+Lucas定理)
- [BZOJ2111][ZJOI2010]Perm 排列计数 && 数学
- BZOJ 2111: [ZJOI2010]Perm 排列计数|组合数学|Lucas定理|DP
- bzoj2111【ZJOI2010】Perm 排列计数
- 【bzoj2111】[ZJOI2010]Perm 排列计数
- BZOJ2111 [ZJOI2010]Perm 排列计数
- BZOJ2111: [ZJOI2010]Perm 排列计数
- bzoj2111 [ZJOI2010]Perm 排列计数
- bzoj2111 Perm 排列计数 组合数学
- BZOJ 2111: [ZJOI2010]Perm 排列计数(简单组合数学)
- BZOJ 2111: [ZJOI2010]Perm 排列计数 DP+lucas定理
- Pascal & C++——USACO Section 1.2 题解
- 文件上传
- 设计模式之策略模式
- linux设置IP
- RxJava框架
- [BZOJ2111][ZJOI2010]Perm 排列计数(组合数学+lucas定理)
- Python学习
- Servlet(1)
- Caffe新手教程傻瓜系列(9):训练和测试自己的图片
- 表示不同文件类型的魔术数字
- JZOJ 3871. 【NOIP2014八校联考第4场第1试10.19】无聊的游戏(game)
- influxdb快速入门
- hive权限控制介绍
- Linux下java程序的依赖运行(上)