Problem E: BST
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 51 Solved: 12
[ Submit][ Status][ Web Board]
Description
A binary search tree is a tree in which every node has at most two children nodes (a left and a right
child). Each node has an integer written inside it. If the number X is written inside a node, then the
numbers in its left subtree are less than X and the numbers in its right subtree are greater than X.
You will be given a sequence of integers between 1 and N (inclusive) such that each number appears in
the sequence exactly once. You are to create a binary search tree from the sequence, putting the first
number in the root node and inserting every other number in order. In other words, run insert(X, root)
for every other number:
insert( number X, node N )
increase the counter C by 1
if X is less than the number in node N
if N has no left child
create a new node with the number X and set it to be the left child of node N
else
insert(X, left child of node N)
else (X is greater than the number in node N)
if N has no right child
create a new node with the number X and set it to be the right child of node N
else
insert(X, right child of node N)
Write a program that calculates the value of the counter C after every number is inserted. The counter
is initially 0.
Input
The first line contains the integer N (1 ≤ N ≤ 300 000), the length of the sequence.
The remaining N lines contain the numbers in the sequence, integers in the interval [1, N]. The
numbers will be distinct.
Output
Output N integers each on its own line, the values of the counter C after each number is inserted into
the tree.
In test cases worth 50% of points, N will be at most 1000.
Sample Input
Sample Output
#include<stdio.h>
#include<string.h>
#define LL(x) (x<<1)
#define RR(x) ((x<<1)|1)
int n;
const int maxn=300005;
struct Seg{
int max;
int min;
int l,r;
}tree[maxn*4];
int dp[maxn+100];
int T[maxn+100];
long long sum;
void build(int l,int r,int k)
{
tree[k].l=l;
tree[k].r=r;
tree[k].max=0;
tree[k].min=n+1;
if(l==r) return ;
int mid=(l+r)>>1;
build(l,mid,LL(k));
build(mid+1,r,RR(k));
}
int Max(int a,int b){
if(a<b) return b;
return a;
}
int Min(int a,int b){
if(a<b) return a;
return b;
}
void update(int l,int r,int k,int v)
{
if(l==r)
{
tree[k].max=tree[k].min=v;
return ;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(v<=mid) update(l,mid,LL(k),v);
else update(mid+1,r,RR(k),v);
tree[k].max=Max(tree[LL(k)].max,tree[RR(k)].max);
tree[k].min=Min(tree[LL(k)].min,tree[RR(k)].min);
}
int query_max(int l,int r,int k)
{
if(l>r) return 0;
if(l<=tree[k].l && tree[k].r<=r)
return tree[k].max;
int mid=(tree[k].l+tree[k].r)>>1;
if(r<=mid) return query_max(l,r,LL(k));
else if(l>mid) return query_max(l,r,RR(k));
else
{
return Max(query_max(l,mid,LL(k)),query_max(mid+1,r,RR(k)));
}
}
int query_min(int l,int r,int k)
{
if(l>r) return 0;
if(l<=tree[k].l && tree[k].r<=r)
return tree[k].min;
int mid=(tree[k].l+tree[k].r)>>1;
if(r<=mid) return query_min(l,r,LL(k));
else if(l>mid) return query_min(l,r,RR(k));
else
{
return Min(query_min(l,mid,LL(k)),query_min(mid+1,r,RR(k)));
}
}
int main()
{
int i,j;
int a,t1,t2;
while(scanf("%d",&n)!=EOF)
{
memset(dp,-1,sizeof(dp));
memset(T,0,sizeof(T));
T[0]=T[n+1]=-1;
build(1,n,1);
sum=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a);
t1=t2=-1;
if(a==1)
{
t1=query_min(2,n,1);
dp[a]=dp[t1]+1;
}
else if(a==n)
{
t1=query_max(1,n-1,1);
dp[a]=dp[t1]+1;
}
else
{
t1=query_max(1,a-1,1);
t2=query_min(a+1,n,1);
if(T[t1]>T[t2])
dp[a]=dp[t1]+1;
else
dp[a]=dp[t2]+1;
}
update(1,n,1,a);//puts("fff");
sum+=dp[a];
T[a]=i;
printf("%lld\n",sum);
}
}
return 0;
}