Bubble Cup 8 finals H. Bots (575H)
题意:
简单来说就是生成一棵树,要求根到每个叶子节点上的路径颜色排列不同,
且每条根到叶子的路径恰有n条蓝边和n条红边。
求生成的树的节点个数。
1<=n<=10^6
题解:
简单计数。
显然,前n层的边的颜色是任意的,所以第i层就是2^i个点。
对于后n层,可以直接由上一层转移。
因为已经知道上一层合法的个数,那么如果现在每个点扩展两条边,
那么上一层的状态中,某种颜色的个数已经达到n的情况就有一条边不可扩展,
所以要减去2*C(i-1,n)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <cstdio> #include <cstring> typedef long long lint; const int N = 2000000, MO = 1000000007; int n,n2,ps,pr[N],fc[N],iv[N],ans; int powmod(int a,int b) { int s = 1; for(;b;b>>=1) { if(b&1) s = (lint)s*a%MO; a = (lint)a*a%MO; } return s; } void init(int n) { int i,j; for(fc[0]=1,i=1;i<=n;i++) fc[i] = (lint)fc[i-1]*i%MO; for(iv[n]=powmod(fc[n],MO-2),i=n;i>=1;i--) iv[i-1] = (lint)iv[i]*i%MO; } inline int getc(int a,int b) { return (lint)fc[a]*iv[a-b]%MO*iv[b]%MO; } int main() { scanf("%d",&n); n2 = n<<1; init(n*2); int i,j,t=1,c=1; ans = 1; for(i=1;i<=n;i++) t = ((lint)t<<1)%MO, ans = ((lint)ans+t)%MO; for(i=n+1;i<=n2;i++) t = (((lint)t<<1)-((lint)getc(i-1,n)<<1))%MO, ans = ((lint)ans+t)%MO; printf("%d\n",(ans+MO)%MO); return 0; }