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;
}
posted @ 2015-12-09 21:24  MoebiusMeow  阅读(612)  评论(0编辑  收藏  举报