Problem 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:java
- 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.ios
![](http://static.javashuo.com/static/loading.gif)
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.web
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
J題:問你一棵有l個葉子的2-3叉樹有多少種拓撲結構,結果對r取餘。。。 2-3叉樹的定義爲全部非葉子節點要麼有2個兒子,要麼有3個兒子,而且全部葉子到根的距離相等。。。 (關於那個O(logn)。。。其實這句話徹底是廢話,貌似好多人被這句廢話給坑到了。。大O只是一個標記,表示漸進的意思,就是說這種樹的高度和葉子數n成漸進對數關係)ui
1 #include<iostream>
2 #include<cstring>
3 #include<cstdlib>
4 #include<cstdio>
5 #include<algorithm>
6 #include<cmath>
7 #include<queue>
8 #include<map>
9 #include<string>
10 //#include<pair>
11
12 #define N 5005
13 #define M 15
14 #define mod 10000007
15 //#define p 10000007
16 #define mod2 100000000
17 #define ll long long
18 #define LL long long
19 #define maxi(a,b) (a)>(b)? (a) : (b)
20 #define mini(a,b) (a)<(b)? (a) : (b)
21
22 using namespace std;
23
24 ll l,r;
25 ll dp[N];
26 ll C[N/2][N/2];
27
28 void ini()
29 {
30 // memset(C,0,sizeof(C));
31 int i,j;
32 for(i=0; i<=l/2; ++i)
33 {
34 C[i][0] = 1;
35 C[i][i] = 1;
36 for(j=1; j<=l/2; ++j){
37 C[i][j] = (C[i-1][j] + C[i-1][j-1]) % r;
38 }
39
40 }
41 }
42
43 void solve()
44 {
45 ll i;
46 ll num;
47 ll st;
48 memset(dp,0,sizeof(dp));
49 dp[0]=0;
50 dp[1]=1;
51 dp[2]=dp[3]=1;
52 for(i=4;i<=l;i++){
53 st=0;
54 if(i%2==1){
55 st=1;
56 }
57 for(;3*st<=i;st+=2){
58 num=st+(i-3*st)/2;
59 dp[i]=(dp[i]+(C[num][st]*dp[num])%r)%r;
60 }
61 }
62 }
63
64
65 void out()
66 {
67 //for(int i=1;i<=l;i++) printf(" i=%d dp=%d\n",i,dp[i]);
68 printf("%lld\n",dp[l]);
69 }
70
71 int main()
72 {
73 // freopen("data.in","r",stdin);
74 //freopen("data.out","w",stdout);
75 //scanf("%d",&T);
76 // for(int ccnt=1;ccnt<=T;ccnt++)
77 // while(T--)
78 while(scanf("%lld%lld",&l,&r)!=EOF)
79 {
80 //if(n==0 && m==0 ) break;
81 //printf("Case %d: ",ccnt);
82 ini();
83 solve();
84 out();
85 }
86
87 return 0;
88 }