LightOJ1170 - Counting Perfect BST(卡特兰数)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LightOJ1170 - Counting Perfect BST(卡特兰数)相关的知识,希望对你有一定的参考价值。

题目大概就是求一个n个不同的数能构造出几种形态的二叉排序树。

和另一道经典题目n个结点二叉树不同形态的数量一个递推解法,其实这两个问题的解都是是卡特兰数。

  • dp[n]表示用n个数的方案数
  • 转移就枚举第几个数作为根,然后分成左右两子树,左右两子树的方案数又是相似子问题

另外就是题目得先找到[1,1e10]的perfect power,总共102230个;输入的区间[a,b],b-a>=1e6,也就是最多perfect power的个数大概就在a=1,b=1000001范围内,1110个perfect power。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<set>
 4 #include<algorithm>
 5 using namespace std;
 6 long long pow(long long x,int y){
 7     long long res=1;
 8     for(int i=0; i<y; ++i) res*=x;
 9     return res;
10 }
11 long long pownum[111111];
12 int pn;
13 int getCnt(long long a,long long b){
14     return (upper_bound(pownum,pownum+pn,b)-pownum)-(lower_bound(pownum,pownum+pn,a)-pownum);
15 }
16 long long d[1111];
17 int main(){
18     for(long long i=2; i*i<=10000000000L; ++i){
19         for(int j=2; ; ++j){
20             if(pow(i,j)>10000000000L) break;
21             pownum[pn++]=pow(i,j);
22         }
23     }
24     sort(pownum,pownum+pn);
25     pn=unique(pownum,pownum+pn)-pownum;
26     d[0]=d[1]=1;
27     for(int i=2; i<1111; ++i){
28         for(int j=1; j<=i; ++j){
29             d[i]+=d[j-1]*d[i-j];
30             d[i]%=100000007;
31         }
32     }
33     d[0]=0;
34     long long a,b;
35     int t;
36     scanf("%d",&t);
37     for(int cse=1; cse<=t; ++cse){
38         scanf("%lld%lld",&a,&b);
39         printf("Case %d: %lld\n",cse,d[getCnt(a,b)]); 
40     }
41     return 0;
42 }

 

以上是关于LightOJ1170 - Counting Perfect BST(卡特兰数)的主要内容,如果未能解决你的问题,请参考以下文章

LightOJ - 1148 Mad Counting(坑)

LightOJ - 1148-Mad Counting (数学)

LightOJ - 1058 - Parallelogram Counting(数学,计算几何)

hdu3887 Counting Offspring

UVa 1225 - Digit Counting - ACM/ICPC Danang 2007 解题报告

codevs1170 双栈排序