您的位置:首页 > 其它

HDU 3240 Counting Binary Trees

2015-05-13 23:48 369 查看


Problem Description

There are 5 distinct binary trees of 3 nodes:



Let T(n) be the number of distinct non-empty binary trees of no more than n nodes, your task is to calculate T(n) mod m.


Input

The input contains at most 10 test cases. Each case contains two integers n and m (1 <= n <= 100,000, 1 <= m <= 109) on a single line. The input ends with n = m = 0.


Output

For each test case, print T(n) mod m.


Sample Input

3 100
4 10
0 0



Sample Output

8
2

卡特兰数+逆元
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const long long maxn = 100005;
long long f[maxn], p[maxn], P = 0, n, m, a[maxn], b[maxn], tot, sum[maxn], ans;

void prime()
{
	memset(f, 0, sizeof(f));
	for (long long i = 2; i < maxn; i++)
	{
		if (!f[i]) p[P++] = i;
		for (long long j = 0; j < P&&i * p[j] < maxn; j++)
		{
			f[i*p[j]] = 1;
			if (i%p[j] == 0) break;
		}
	}
}

void break_down(long long x)
{
	tot = 0;
	for (long long i = 0; i < P; i++)
	{
		if (x%p[i] == 0) a[tot++] = p[i];
		while (x % p[i] == 0) x /= p[i];
	}
}

/*long long inv(long long x, long long mod)
{
if (mod % x == 0) return x;
return inv(mod % x, mod)*(mod - mod / x) % mod;
}*/

void egcd(long long a, long long b, long long &x, long long &y)
{
	if (b == 0)
	{
		x = 1, y = 0;
		return;
	}
	egcd(b, a%b, x, y);

	long long t = x;
	x = y, y = t - a / b*y;

	return;
}

long long insert(long long x, long long y)
{
	for (long long i = 0; i < tot; i++)
	{
		while (x % a[i] == 0) b[i]++, x /= a[i];
		while (y % a[i] == 0) b[i]--, y /= a[i];
	}
	long long i, j;
	egcd(y, m, i, j);
	return x * i % m;
}

long long get()
{
	long long ans = 1;
	for (long long i = 0; i < tot; i++)
	for (long long j = 1; j <= b[i]; j++) (ans *= a[i]) %= m;
	return ans;
}

int main()
{
	prime();
	while (cin >> n >> m, n + m)
	{
		break_down(m);
		memset(b, 0, sizeof(b));
		memset(sum, 0, sizeof(sum));
		ans = 0;
		for (long long i = sum[0] = 1; i <= n; i++)
		{
			sum[i] = sum[i - 1] * insert(i * 4 - 2, i + 1) % m;
			(ans += sum[i] * get()) %= m;
		}
		cout << (ans + m) % m << endl;
	}
	return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: