ZCMU01934: ly的二叉树(卡特兰数)

20 篇文章 0 订阅

1934: ly的二叉树

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 52  Solved: 16
[Submit][Status][Web Board]

Description

某一天,ly正在上数据结构课。老师在讲台上面讲着二叉树,ly在下面发着呆。
突然ly想到一个问题:对于一棵n个无编号节点的有根二叉树,有多少种形态呐?你能告诉她吗?

 

Input

多组输入,处理到文件结束
每一组输入一行,一个正整数n(1≤n≤1000000),意义如题目所述。

 

Output

每组数据输出一行,包含一个正整数表示答案,由于数字可能非常大,你只需要把最后的结果对1000000007取模即可。

 

Sample Input

3

Sample Output

5

HINT

 

Source

jnxxhzz

 

【解析】

这题,很难,很难,很难。

因为。我。没。学过。但是我。会百度。yeah。

首先呢,这个题目是数学问题,人家研究完了,是一个叫卡特兰数的东西。

具体是什么,卡特兰数,看这个,大概能懂什么是卡特兰数,反正这题答案就是这个,为什么,问数学家,看博客。

所以我们现在已知的就是:

以及,递推公式:C(n)=C(n-1)*((4*n-2)/(n+1));

问题是,这题n很大,不可能朴素的打表过。所以就涉及到模的问题。我们知道加减乘都是有取余的法则的(不懂的我也找到了博客取模运算法则及性质),但是这里出现了除法,所以就要学一个新知识(我新学的),逆元,简单解释就是把除法变成乘法运算,然后再取模,但是这个学逆元又要学费马小定理 费马定理推导 。看不太懂也别担心,先会结论然后慢慢磨就好了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
const int maxn = 1000010;
ll tab[maxn];
ll quick_pow(ll a, ll b)//快速幂求逆元
{
	ll ans = 1;
	a %= mod;
	while (b)
	{
		if (b & 1)
			ans = ans * a % mod;
		b = b >> 1;
		a = a * a%mod;
		//a*=a%mod;错误
	}
	return ans;
}
void f()
{
	tab[0] = tab[1] = 1;
	for (int i = 2; i < maxn; i++)
		tab[i] = tab[i - 1] * (4 * i - 2) % mod*quick_pow(i + 1, mod - 2) % mod;
}
int main()
{
	int n;
	f();
	while (~scanf("%d", &n))
		printf("%lld\n", tab[n]);

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值