ACdream 1412 2-3 Trees

Description

      2-3 tree is an elegant data structure invented by John Hopcroft. It is designed to implement the same functionality as the binary search tree. 2-3 tree is an ordered rooted tree with the following properties:

  • the root and each internal vertex have either 2 or 3 children;
  • the distance from the root to any leaf of the tree is the same.

      The only exception is the tree that contains exactly one vertex — in this case the root of the tree is the only vertex, and it is simultaneously a leaf, i.e. has no children. The main idea of the described properties is that the tree with l leaves has the height O(log l).
      Given the number of leaves l there can be several valid 2-3 trees that have l leaves. For example, the picture below shows the two possible 2-3 trees with exactly 6 leaves.


      Given l find the number of different 2-3 trees that have l leaves. Since this number can be quite large, output it modulo r.

Input

      Input file contains two integer numbers: l and r (1 ≤ l ≤ 5 000, 1 ≤ r ≤ 10  9).

Output

      Output one number — the number of different 2-3 trees with exactly l leaves modulo r.

Sample Input

6 1000000000
7 1000000000

Sample Output

2

3

dp递推+暴力求组合数

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const long long maxn = 2505;
long long f[maxn],c[maxn][maxn],n,m;

int main()
{
	while (cin >> n >> m)
	{
		memset(f, 0, sizeof(f));
		for (int i=1;i+i<=n;i++)
		{
			c[i][0]=c[i][i]=1;
			for (int j=1;j<i;j++) 
				c[i][j]=(c[i-1][j-1]+c[i-1][j])%m;
		}
		f[1]=1;
		for (long long i=2;i<=n;i++)
		{
			f[i]=0;
			for (long long j=0;j+j+j<=i;j++)
			if ((i-3*j)%2==0)
			{
				(f[i]+=f[j+(i-3*j)/2]*c[j+(i-3*j)/2][j])%m;
				(f[i]+=m)%=m;
			}
		}
		cout<<f[n]%m<<endl;
	}
	return 0;
}


你可能感兴趣的:(ACdream)