acdream 1412 2-3 Trees

2-3 Trees

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

SubmitStatus

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

题解及代码:

这是一个DP题目,其实就是找到每一层上2*x+3*y=n的解的情况,然后由这一层推到上一层2*x‘+2*y’=x+y,依次类推,直到最高层。

注意:2 2 3  与2 3 2 是不同的情况,所以要用到组合数。我一开始直接开long long的数组,爆内存了,后来改写成int ,然后数组开小为原来的1/8,才过。

也看了一下别人的代码,直接用的滚动数组,更省内存,而且速度也很快。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
typedef long long LL;
LL sum[5010];
int bt[2510][1300];
int N,R;
bool flag[5010];

struct node
{
    int x,y;
    node(int X,int Y)
    {
        x=X;y=Y;
    }
};

struct Root
{
    vector<node> nt;

}r[5010];

void get(int n)
{
    if(flag[n]) return;
    int j;
    for(int i=0;i*2<=n;i++)
    {
        j=n-i*2;
        if(j>=0&&j%3==0)
        r[n].nt.push_back(node(i,j/3));
    }
    flag[n]=true;
}

void init()
{
    memset(sum,-1,sizeof(sum));
    memset(flag,false,sizeof(flag));
    sum[1]=0;sum[2]=1;sum[3]=1;
    bt[1][0]=bt[1][1]=1;bt[1][2]=0;
    int bN=N/2+1;
    int bM=bN/2+1;
    get(N);

    for(int i=2;i<=bN;i++)
    {
        bt[i][0]=1;
        for(int j=1;j<=bM;j++)
        {
            bt[i][j]=(bt[i-1][j-1]+bt[i-1][j])%R;
        }
    }
}

LL dfs(int n)
{
    if(sum[n]>=0) return sum[n];
    int len=r[n].nt.size();
    LL ans=0;int k;
    for(int i=0;i<len;i++)
    {
        k=r[n].nt[i].x+r[n].nt[i].y;
        get(k);
        ans=(ans+bt[k][min(r[n].nt[i].x,r[n].nt[i].y)]*dfs(k))%R;
    }
    //printf("%d  %d\n",n,ans);
    sum[n]=ans;
    return ans;
}

int main()
{
    while(scanf("%d%d",&N,&R)!=EOF)
    {
        if(N==1)
        {
            printf("%d\n",N%R);
            continue;
        }
        init();
        LL an=dfs(N);
        printf("%lld\n",an);
    }
    return 0;
}
时间: 2024-11-03 21:18:50

acdream 1412 2-3 Trees的相关文章

acdream 1412 2-3Trees (组合+DP)

题意:2-3树的每个结点(除了叶子外)有2或3个孩子(分支),假设是一个满2-3树,那么给出叶子的数量,求这样的树有多少棵.(注:有2个孩子的结点视为相同,有3个孩子的结点视为相同,比如倒数第2层有4个结点,且叶子有4+6=10个,即2个有2孩的结点在前面,2个有3孩的结点在后面,那么头两个结点的孩子互换是视为相同的,如下图) 只要结点1234各自的孩子数不变,则视为同棵树.若具有2孩的结点跟具有3孩的结点换位置,则为不同树,比如1和3换个位置.) 思路: (1)考虑DP,依靠叶子数量小的,推出

ACdream原创群赛(16) F

MST Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitStatus Problem Description Given a connected, undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices togeth

ACdream 1135(MST-最小生成树边上2个值,维护第一个最小的前提下让另一个最小)

F - MST Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitStatus Problem Description Given a connected, undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices to

ACdream 1135 MST

MST Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) Problem Description Given a connected, undirected graph, a spanning tree of that graph is a subgraph that is a tree and connects all the vertices together.  A single

LeetCode OJ :Unique Binary Search Trees II(唯一二叉搜索树)

题目如下所示:返回的结果是一个Node的Vector: Given n, generate all structurally unique BST's (binary search trees) that store values 1...n. For example,Given n = 3, your program should return all 5 unique BST's shown below. 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2

CSU 1412 Line and Circles

原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1412 题目要求判断是否有一条直线可以穿过所有的圆. 做法:把所有圆心做一次凸包,然后判断这个凸包是否能通过一个宽度为2*R的通道. 做法和求凸包直径差不多,只是判断的时候把点到两个端点的距离换成点到直线的距离. #include <stdio.h> #include <string.h> #include <math.h> #include <stdli

51nod 1412 AVL树的种类(经典dp)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1412 题意: 思路: 经典dp!!!可惜我想不到!! $dp[i][k]$表示i个结点,最大深度为k的形态数. 它的转移方程就是: dp[i][k] += dp[i - 1 - j][k - 1] * dp[j][k - 1] dp[i][k] += 2 * dp[i - 1 - j][k - 2] * dp[j][k - 1] j是右子树结点个数,如果除去根结点,是不

HDOJ 4010 Query on The Trees LCT

LCT: 分割.合并子树,路径上全部点的点权添加一个值,查询路径上点权的最大值 Query on The Trees Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 2582    Accepted Submission(s): 1208 Problem Description We have met so many problems

96. Unique Binary Search Trees

Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For example,Given n = 3, there are a total of 5 unique BST's. 1 3 3 2 1 \ / / / \ 3 2 1 1 3 2 / / \ 2 1 2 3 对1-n组成的BST,如果选定i为根,那1-(i-1)都在根的左子树里,(i+1)-n都在根的右子树里