zoukankan      html  css  js  c++  java
  • P4609 [FJOI2016]建筑师

    P4609 [FJOI2016]建筑师

    首先注意到 (n) 这个高度很特殊,因为它是左边看到的最后一个建筑,也是右边看到的最后一个建筑,也就是说,它是分界点。

    (n) 左边有 (A-1) 分割点,每一段都是递减的,最高的那个是开头,也就是分割点。

    这样就能满足从左往右看到 (A) 个高度了。

    右边同理。

    发现我们可以直接用第一类斯特林数的定义了!!!

    答案就是把 (n-1) 划分成 (A+B-2) 个循环的方案,其中 (n) 因为没法动被去除了。

    因为对于每一个循环只有一种高度排列合法(即最高的放最后或者最前),而循环也恰好会被统计一次,也就是说这两个东西是一一对应的。

    (A+B-2) 个循环还要选 (A-1) 个放到 (n) 左边,所以还得乘组合数。

    那么答案就是

    [egin{bmatrix}n-1\A+B-2end{bmatrix}inom{A+B-2}{A-1} ]

    所以这题唯一的考点对于第一类斯特林数的熟练程度。

    int S1[50005][205],fac[205],ifc[205];
    #define mod 1000000007
    inline int qpow(int n,int k){int res=1;for(;k;k>>=1,n=1ll*n*n%mod)if(k&1)res=1ll*n*res%mod;return res;}
    int comb(int n,int m){return n<m?0:1ll*fac[n]*1ll*ifc[m]%mod*ifc[n-m]%mod;}
    void init(){
    	fac[0]=1;rep(i,1,200)fac[i]=1ll*fac[i-1]*i%mod;
    	ifc[200]=qpow(fac[200],mod-2);per(i,199,0)ifc[i]=1ll*ifc[i+1]*(i+1)%mod;
    	S1[0][0]=1;rep(i,1,50000)rep(j,1,200)S1[i][j]=(S1[i-1][j-1]+1ll*S1[i-1][j]*(i-1)%mod)%mod;
    }
    signed main(){
    	init();
    	for(int T=read();T;--T){
    		int n=read(),A=read(),B=read();
    		if(A+B-1>n)puts("0");
    		else printf("%lld
    ",1ll*comb(A+B-2,A-1)*S1[n-1][A+B-2]%mod);
    	}
    	return 0;
    }
    
  • 相关阅读:
    BOM与DOM
    CSS中的长度单位及颜色表示
    关于display:grid layout
    关于position
    简单的注册表单
    We重邮
    APP定制开发的完整流程
    国内移动广告平台的混战大盘点
    Mobile App Monetization, Analysis & Mediation – Google AdMob
    代码优化
  • 原文地址:https://www.cnblogs.com/zzctommy/p/14273864.html
Copyright © 2011-2022 走看看