CodeForce 675D

题意:输入n,输入n个结点,第一个结点为根节点,构造平衡树,

从第二个结点开始输出每个结点的父结点

题解:用set数组存储输入结点,可自动从小到大排序,便于二分查找比a[i]结点大的数

若a[i]为最大值则他为根节点的右子树,若可以找到比a[i]大的结点,检查该节点的左子树

是否有值,若没有a[i]为该节点的左子树,否则为该节点在set中的位置-1的右子树。

map容器l,r标记树的左右结点是否有值存在。

#include<cstdio>
#include<iostream>
#include<set>
#include<map>
using namespace std;
int a[100005],n;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        set<int>s;
        scanf("%d",&a[1]);
        s.insert(a[1]);
        int flag=0;
        map<int,int>l,r;//标记左右子树是否 有值 
        for(int i=2;i<=n;i++)
        {
            if(i>2)
                cout<<" ";
            scanf("%d",&a[i]);
            set<int>::iterator ite;
            ite=s.lower_bound(a[i]);
            if(ite==s.end())//没有找到比他大的值,此时a[i]最大,应该为set中最大值的右子树 
            {
                printf("%d",*(--ite));
                r[*ite]=1;
            }
            else//找到比他大的数, 
            {
                if(l[*ite]==1)//如果该树左子树已有值,应为比该树小的数(set)的右子树 
                {
                    printf("%d",*(--ite));
                    r[*ite]=1;
                }
                else//否则为该树的左子树 
                {
                    printf("%d",*(ite));
                    l[*ite]=1;
                }
            }
            s.insert(a[i]);//压入set容器 
        }
        cout<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/renwjing/p/7384466.html