codeforces 675D D. Tree Construction(线段树+BTS)

题目链接:

D. Tree Construction

D. Tree Construction
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

During the programming classes Vasya was assigned a difficult problem. However, he doesn't know how to code and was unable to find the solution in the Internet, so he asks you to help.

You are given a sequence a, consisting of n distinct integers, that is used to construct the binary search tree. Below is the formal description of the construction process.

  1. First element a1 becomes the root of the tree.
  2. Elements a2, a3, ..., an are added one by one. To add element ai one needs to traverse the tree starting from the root and using the following rules:
    1. The pointer to the current node is set to the root.
    2. If ai is greater than the value in the current node, then its right child becomes the current node. Otherwise, the left child of the current node becomes the new current node.
    3. If at some point there is no required child, the new node is created, it is assigned value ai and becomes the corresponding child of the current node.
 
Input
 

The first line of the input contains a single integer n (2 ≤ n ≤ 100 000) — the length of the sequence a.

The second line contains n distinct integers ai (1 ≤ ai ≤ 109) — the sequence a itself.

 

Output
 

Output n - 1 integers. For all i > 1 print the value written in the node that is the parent of the node with value ai in it.

Examples
 
input
3
1 2 3
output
1 2
input
5
4 2 3 1 6
output
4 2 2 4


题意:

给一个序列,构造一个二叉搜索树,然后输出每个节点的父节点;


思路:

在构造二叉搜索树的时候,每插入一个节点时它的插入位置是一定的,要么插在最大的比它小的数的右边,要么插在最小的比它
大的数左边,用线段树维护最大最小值就可以了;也可以用set+map模拟建树的过程;

AC代码:


#include <bits/stdc++.h>
/*
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <cstring>
#include <algorithm>
#include <cstdio>
*/
using namespace std;
#define Riep(n) for(int i=1;i<=n;i++)
#define Riop(n) for(int i=0;i<n;i++)
#define Rjep(n) for(int j=1;j<=n;j++)
#define Rjop(n) for(int j=0;j<n;j++)
#define mst(ss,b) memset(ss,b,sizeof(ss));
typedef long long LL;
const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=0x3f3f3f3f;
const int N=1e5+25;
int n,l[N],r[N],f[N];
struct Tree
{
    int l,r,mmin,mmax;
}tree[4*N];
void pushup(int node)
{
    tree[node].mmin=min(tree[2*node].mmin,tree[2*node+1].mmin);
    tree[node].mmax=max(tree[2*node].mmax,tree[2*node+1].mmax);
}
void build(int node,int L,int R)
{
    tree[node].l=L;
    tree[node].r=R;
    tree[node].mmax=0;
    tree[node].mmin=inf;
    if(L==R)return ;
    int mid=(L+R)>>1;
    build(2*node,L,mid);
    build(2*node+1,mid+1,R);
}
void update(int node,int pos)
{
   // cout<<tree[node].l<<" "<<tree[node].r<<" "<<pos<<"@"<<"\n";
    if(tree[node].l==tree[node].r&&tree[node].l==pos)
    {
        tree[node].mmax=tree[node].mmin=pos;
        return ;
    }
    int mid=(tree[node].l+tree[node].r)>>1;
    if(pos<=mid)update(2*node,pos);
    else update(2*node+1,pos);
    pushup(node);
}
int query(int node,int L,int R,int flag)
{
    if(L<=tree[node].l&&R>=tree[node].r)
    {
        if(flag)return tree[node].mmax;
        else return tree[node].mmin;
    }
    int mid=(tree[node].l+tree[node].r)>>1;
    if(R<=mid)return query(2*node,L,R,flag);
    else if(L>mid)return query(2*node+1,L,R,flag);
    else
    {
        if(flag)return max(query(2*node,L,mid,flag),query(2*node+1,mid+1,R,flag));
        else return min(query(2*node,L,mid,flag),query(2*node+1,mid+1,R,flag));
    }
}
struct Po
{
    int a,pos,num;
}po[N];
int cmp1(Po x,Po y)
{
    return x.a<y.a;
}
int cmp2(Po x,Po y)
{
    return x.pos<y.pos;
}
int main()
{
    scanf("%d",&n);
    build(1,1,n);
    Riep(n)
    {
        scanf("%d",&po[i].a);
        po[i].pos=i;
    }
    sort(po+1,po+n+1,cmp1);
    Riep(n)po[i].num=i,f[i]=po[i].a;
    sort(po+1,po+n+1,cmp2);
    update(1,po[1].num);
    for(int i=2;i<=n;i++)
    {
        int s=query(1,1,po[i].num,1);
        if(s==0||(s!=0&&r[s]))
        {
            s=query(1,po[i].num,n,0);
            l[s]=po[i].num;
        }
        else
        {
            r[s]=po[i].num;
        }
        update(1,po[i].num);
        printf("%d ",f[s]);
    }

    return 0;
}

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>
#include <map>
 
using namespace std;
 
#define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss));
 
typedef  long long LL;
 
template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
    for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
    F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
    if(!p) { puts("0"); return; }
    while(p) stk[++ tp] = p%10, p/=10;
    while(tp) putchar(stk[tp--] + '0');
    putchar('\n');
}
 
const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9+10;
const int N=1e5+10;
const int maxn=1e3+20;
const double eps=1e-12;


set<int>s;
map<int,int>le,ri;
set<int>::iterator it; 
int main()
{
    int n,x;
    read(n);
    read(x);s.insert(x);
    For(i,2,n)
    {
        read(x);
        it=s.lower_bound(x);
        int pos=*it;
        if(le[pos]==0&&it!=s.end())le[pos]=x;
        else 
        {
            it--;
            pos=*it;
            ri[pos]=x;
        }
        s.insert(x);
        printf("%d ",pos);
    }
    return 0;
}

  

posted @ 2016-05-17 18:40  LittlePointer  阅读(431)  评论(0编辑  收藏  举报