zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    【tarjan】BZOJ 1051:受欢迎的牛
    【递推】BZOJ 1088: [SCOI2005]扫雷Mine
    【计算几何】多边形
    【贪心】Bzoj 2457:[BeiJing2011]双端队列
    【单调栈】Bzoj 1012: 最大数maxnumber
    [洛谷P3584] POI2015 LAS
    [洛谷P4049] JSOI2007 合金
    [51nod1533] 一堆的堆
    [AGC018E] Sightseeing Plan
    [CF1065E] Side Transmutations
  • 原文地址:https://www.cnblogs.com/renwjing/p/7384466.html
Copyright © 2011-2022 走看看