1170 - Counting Perfect BST

  PDF (English) Statistics Forum
Time Limit: 2 second(s) Memory Limit: 32 MB

BST is the acronym for Binary Search Tree. A BST is a tree data structure with the following properties.

i)        Each BST contains a root node and the root may have zero, one or two children. Each of the children themselves forms the root of another BST. The two children are classically referred to as left child and right child.

ii)      The left subtree, whose root is the left children of a root, contains all elements with key values less than or equal to that of the root.

iii)    The right subtree, whose root is the right children of a root, contains all elements with key values greater than that of the root.

An integer m is said to be a perfect power if there exists integer x > 1 and y > 1 such that m = xy. First few perfect powers are {4, 8, 9, 16, 25, 27, 32, 36, 49, 64, 81, 100, 121, 125, 128, 144, ...}. Now given two integer a and b we want to construct BST using all perfect powers between a and b, where each perfect power will form the key value of a node.

Now, we can construct several BSTs out of the perfect powers. For example, given a = 1 and b = 10, perfect powers between a and b are 4, 8, 9. Using these we can form the following five BSTs.

4           4         8          9         9

  \          \      / \      /         /

    8          9   4     9   4         8

      \      /                 \      /

9   8                     8   4

In this problem, given a and b, you will have to determine the total number of BSTs that can be formed using perfect powers between a and b.

Input

Input starts with an integer T (≤ 20000), denoting the number of test cases.

Each case of input contains two integers: a and b (1 ≤ a ≤ b ≤ 1010, b - a ≤ 106) as defined in the problem statement.

Output

For each case, print the case number and the total number of distinct BSTs that can be formed by the perfect powers between a and b. Output the result modulo 100000007.

Sample Input

Output for Sample Input


4

1 4

5 10

1 10

1 3


Case 1: 1

Case 2: 2

Case 3: 5

Case 4: 0



Problem Setter: Shamim Hafiz

Special Thanks: Jane Alam Jan

题意:给定一个区间范围a,b,a,b内所以可以表示为x^y的数字可以组成的二叉排序树有多少种;

思路:n个节点能够成的二叉排序树种类是卡特兰数;

定义一个数是基,当且仅当这个数不是另一个数的幂次方。我们可以在近似O(nlogn)的时间内找出[1,100000]内的所有的基。

然后对于每一个幂次k,通过二分找出x^k 在所给范围内的基的个数,累加即可求得。

卡特兰数打表就行,要用费马小定理求逆元。

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string.h>
  5 #include<queue>
  6 #include<stdlib.h>
  7 #include<math.h>
  8 #include<stack>
  9 using namespace std;
 10 typedef unsigned long long  LL;
 11 bool pr[100005];
 12 int ans[100005];
 13 LL KTL[1000006];
 14 const int N=1e8+7;
 15 LL quick(LL n,LL m)
 16 {
 17         LL ak=1;
 18         while(m)
 19         {
 20                 if(m&1)
 21                 {
 22                         ak=(ak*n)%N;
 23                 }
 24                 n=(n*n)%N;
 25                 m/=2;
 26         }
 27         return ak;
 28 }
 29 LL qu(LL n,LL m,LL ask)
 30 {
 31         LL ak=1;
 32         while(m)
 33         {
 34                 if(m&1)
 35                 {
 36                         ak*=n;
 37                         if(ak>ask)
 38                                 return 0;
 39                 }
 40                 n*=n;
 41                 if(n>ask&&m!=1)return 0;
 42                 m/=2;
 43         }
 44         if(ak<=ask)
 45         {
 46                 return 1;
 47         }
 48 }
 49 LL qu1(LL n,LL m, LL ac)
 50 {
 51         LL ak=1;
 52         while(m)
 53         {
 54                 if(m&1)
 55                 {
 56                         ak*=n;
 57                         if(ak>ac)
 58                         {
 59                                 return 1;
 60                         }
 61                 }
 62                 n*=n;
 63                 if(n>ac&&m!=1)return 1;
 64                 m/=2;
 65         }
 66         if(ak<ac)
 67         {
 68                 return 0;
 69         }
 70         else return 1;
 71 }
 72 int main(void)
 73 {
 74         int i,j,k;
 75         scanf("%d",&k);
 76         int s;
 77         LL n,m;
 78         memset(pr,0,sizeof(pr));
 79         for(i=2; i<1000; i++)
 80         {
 81                 if(!pr[i])
 82                 {
 83                         for(j=i; i*j<=100000; j*=i)
 84                         {
 85                                 pr[i*j]=true;
 86                         }
 87                 }
 88         }
 89         int cnt=0;
 90         for(i=2; i<=100000; i++)
 91         {
 92                 if(!pr[i])
 93                 {
 94                         ans[cnt++]=i;
 95                 }
 96         }
 97         KTL[1]=1;
 98         KTL[2]=2;
 99         KTL[3]=5;
100         for(i=4; i<=1000000; i++)
101         {
102                 KTL[i]=KTL[i-1]*(4*i-2)%N;
103                 KTL[i]=KTL[i]*(quick((LL)(i+1),(LL)(N-2)))%N;
104         }
105         for(s=1; s<=k; s++)
106         {
107                 int sum=0;
108                 scanf("%lld %lld",&n,&m);
109                 for(i=2; i<=34; i++)
110                 {
111                         int l=0;
112                         int r=cnt-1;
113                         int id=-1;
114                         while(l<=r)
115                         {
116                                 int mid=(l+r)/2;
117                                 int flag=qu((LL)ans[mid],(LL)i,m);
118                                 if(flag)
119                                 {
120                                         id=mid;
121                                         l=mid+1;
122                                 }
123                                 else r=mid-1;
124                         }
125                         l=0;
126                         r=cnt-1;
127                         int id1=-1;
128                         while(l<=r)
129                         {
130                                 int mid=(l+r)/2;
131                                 int flag=qu1((LL)ans[mid],(LL)i,n);
132                                 if(flag)
133                                 {
134                                         id1=mid;
135                                         r=mid-1;
136                                 }
137                                 else l=mid+1;
138                         }
139
140                         if(id1<=id&&id!=-1)sum+=id-id1+1;
141                 }
142                 printf("Case %d: ",s);
143                 printf("%lld\n",KTL[sum]);
144
145         }
146         return 0;
147 }
时间: 2024-08-03 20:18:29

1170 - Counting Perfect BST的相关文章

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个perfec

matlab deckShuffling

% a script to determine how many perfect shuffles are required % before a given deck of cards returns to its original order clear all, close all % problem statement: % suppose we have a deck of 8 (distinct) cards % 1 2 3 4 5 6 7 8 % define a perfect

[二叉查找树] 1115. Counting Nodes in a BST (30)

1115. Counting Nodes in a BST (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains only nod

UVALive 5058 Counting BST 数学

B - Counting BST Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVALive 5058 Description Binary Search Tree (BST) is a rooted binary tree data structure which has following properties: Left subtree conta

1115 Counting Nodes in a BST (30 分)建立二叉搜索树,求每层结点数目

1115 Counting Nodes in a BST (30 分) A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains only nodes with keys less than or equal to the node's key. The right subtre

1115 Counting Nodes in a BST (30)

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains only nodes with keys less than or equal to the node's key. The right subtree of a node contains only nodes with

PAT 1115 Counting Nodes in a BST

A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains only nodes with keys less than or equal to the node's key. The right subtree of a node contains only nodes with

PAT (Advanced Level) 1115. Counting Nodes in a BST (30)

简单题.统计一下即可. #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<map> #include<queue> #include<stack> #include<algorithm> using namespace std; const int maxn=100000+10; struct Node {

PAT A 1115. Counting Nodes in a BST (30)【二叉排序树】

1115 题目:二叉排序树,统计最后两层节点个数 思路:数组格式存储,insert建树,dfs遍历 #include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const int INF = 0x7FFFFFFF; const int maxn = 1e5 + 10; int n, cn