Andrew Stankevich's Contest (21) J dp+组合数

坑爹的,,组合数模板,,,

 

6132 njczy2010 1412 Accepted 5572 MS 50620 KB C++ 1844 B 2014-10-02 21:41:15

 

J - 2-3 Trees

Time Limit: 12000/6000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)

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:

  • 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 ≤ 109).

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

 

题解转自:http://acdream.info/topic?tid=3623

J题:问你一棵有l个叶子的2-3叉树有多少种拓扑结构,结果对r取余。。。 2-3叉树的定义为所有非叶子节点要么有2个儿子,要么有3个儿子,并且所有叶子到根的距离相等。。。 (关于那个O(logn)。。。其实这句话完全是废话,貌似好多人被这句废话给坑到了。。大O只是一个标记,表示渐进的意思,就是说这种树的高度和叶子数n成渐进对数关系)

J题:首先预处理出前2500行的组合数(杨辉三角递推即可,别忘了取余),然后初始化dp[1]=1,若只有根,也有一种情况
然后进行dp,注意到一个性质,2-3树的所有叶子都在同一层,于是就可以通过排列组合来计算叶子的方法数。
于是就转移到了上一层的情况,一层一层记忆化上去,或者递推下来= =。。反正是单组数据~~~

 

 

注意用 lld。。。

 

 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 }

 

posted on 2014-10-02 21:45  njczy2010  阅读(268)  评论(0编辑  收藏  举报