zoukankan      html  css  js  c++  java
  • BZOJ.2111.[ZJOI2010]排列计数(DP Lucas)

    题目链接

    对于(a_i>a_{i/2}),我们能想到小根堆。题意就是,求构成大小为(n)的小根堆有多少种方案。
    考虑DP,(f[i])表示构成大小为(i)的小根堆的方案数,那么如果我们确定左右子树(size),则左右子树又分别是一个子问题。
    那么可以得到转移方程:(f[i]=C_{i-1}^l*f[l]*f[r])
    因为是按顺序填满二叉树的每一层,所以左子树大小是确定的啊。

    (P)给定,可能(leq n),所以要用Lucas定理求组合数。

    //12540kb	536ms(不知道为什么慢...)
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    const int N=1e6+5;
    
    int f[N],fac[N],inv[N];
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now;
    }
    inline int FP(int x,int k,int P)
    {
    	int t=1;
    	for(; k; k>>=1,x=1ll*x*x%P)
    		if(k&1) t=1ll*t*x%P;
    	return t;
    }
    int Calc(int n,int m,int P)
    {
    	if(n<m) return 0;
    	return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;
    }
    int C(int n,int m,int P)
    {
    	int res=1;
    	for(; n&&m; n/=P,m/=P)
    		res=1ll*res*Calc(n%P,m%P,P)%P;
    	return res;
    }
    
    int main()
    {
    	int n=read(), P=read();
    	int lim=std::min(n,P-1);
    	fac[0]=1;
    	for(int i=1; i<=lim; ++i) fac[i]=1ll*fac[i-1]*i%P;
    	inv[lim]=FP(fac[lim],P-2,P);
    	for(int i=lim-1; ~i; --i) inv[i]=1ll*inv[i+1]*(i+1)%P;//inv[0]!
    
    	f[1]=f[2]=1, f[3]=2;
    	for(int i=4,l=1,now=2,mx=3,lim=1; i<=n; ++i)
    	{
    		if(mx<i) lim+=now, mx+=(now<<=1);
    		if(l<lim) ++l;
    		f[i]=1ll*C(i-1,l,P)*f[l]%P*f[i-1-l]%P;
    	}
    	printf("%d
    ",f[n]);
    
    	return 0;
    }
    
    ------------------------------------------------------------------------------------------------------------------------
    无心插柳柳成荫才是美丽
    有哪种美好会来自于刻意
    这一生波澜壮阔或是不惊都没问题
    只愿你能够拥抱那种美丽
    ------------------------------------------------------------------------------------------------------------------------
  • 相关阅读:
    网页内容自动换行
    问题:Sql Server登录不进去的问题
    Truncate的用法
    SQL当前日期获取技巧
    .NET导出Excel遇到的80070005错误的解决
    养眼方式
    在页面里显示出PPT的效果
    问题(待解决):运行NCover产生的问题
    用CSS控制输入框输入的字母自动转入都是大写字母
    问题:Default引起的问题
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9664650.html
Copyright © 2011-2022 走看看