洛谷 P2606 [ZJOI2010]排列计数 分析
题意可以简化为用 的数,组成一个完全二叉树,使其满足小根堆性质,求方案数。
令 表示在 点的方案数, 表示 的子节点个数(包括 ),于是得出递推式:
由于 BZOJ 上 (可能),所以需要用 Lucas 定理。
namespace LZX { using namespace std; #define int long long const int MAXN=2000015; int fac[MAXN],s[MAXN],f[MAXN]; int math_qpow(int base,int power,int mod) { int res=1; while(power) { if(power&1) { res=res*base%mod; } base=base*base%mod; power>>=1; } return res; } int math_C(int n,int m,int p) { return fac[n]*math_qpow(fac[m]*fac[n-m]%p,p-2,p)%p; } int math_lucas(int n,int m,int p) { if(!m) { return 1; } if(m>n) { return 0; } return math_C(n%p,m%p,p)*math_lucas(n/p,m/p,p)%p; } int _main() { int n,m; scanf("%lld%lld",&n,&m); fac[0]=1; for(int i=1;i<=n;i++) { fac[i]=fac[i-1]*i%m; } fill(s+1,s+n+1,1); for(int i=n;i>=2;i--) { s[i>>1]+=s[i]; } fill(f+n+1,f+n*2+2,1); for(int i=n;i;i--) { f[i]=math_lucas(s[i]-1,s[i<<1],m)%m*f[i<<1]%m*f[i*2+1]%m; } printf("%lld\n",f[1]); return 0; } }
本文作者:Day_Dreamer_D's Blog
本文链接:https://www.cnblogs.com/2020gyk080/p/16284504.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步