• 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<<"@"<<"
    ";
        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('
    ');
    }
     
    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;
    }
    

      

  • 相关阅读:
    前端通过Nginx反向代理解决跨域问题
    SpringMVC解决跨域问题
    SpringMVC空字符串转为null
    什么是优秀的程序员
    Windows下Nginx实现负载均衡
    SpringMVC实现PUT请求上传文件
    设计模式解密(6)
    设计模式解密(5)- 外观模式(门面模式)
    设计模式解密(4)- 模板方法模式
    eclipse上传新项目到GitHub
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5502749.html
Copyright © 2020-2023  润新知