codeforces 675D Tree Construction 数据结构

题目链接:http://www.codeforces.com/contest/675/problem/D

题意:

依次给出每个节点的值,要求最终得到一颗二叉排序树,第一个节点是根,求每个节点的父节点。

思路:

对于每个插入的节点,要么成为比它小的最大的节点右儿子,要么成为比它大的最小节点的左儿子。

把每个节点依次放入set里面用lower_bound查找就可以了。

顺便复习了一下set:

lower_bound(x)返回集合中大于或者等于x的第一个值的位置,如果找不到返回s.end()

upper_bound(x)返回集合中大于x的第一个位置,如果找不到返回s.end()

指针变量不能加和减,但是可以++或者--。

set中最后一个数的值应该为*(--s.end())

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int n;
 4 int a[100010];
 5 int main() 
 6 {
 7     //freopen("in.txt", "r", stdin);
 8     while(~scanf("%d", &n))
 9     {
10         set <int> s;
11         scanf("%d", &a[1]);
12         s.insert(a[1]);
13         
14         bool flag = false;
15         map <int, int> l, r;
16         for(int i = 2; i <= n; i++)
17         {
18             if(i > 2) printf(" ");
19             scanf("%d", &a[i]);
20             set <int>::iterator it = s.lower_bound(a[i]);
21             if(it == s.end())  //找第一个比它大的数,如果没找到,说明这个数最大,只能在最后的右儿子
22             {
23                 set <int>::iterator it2 = --s.end();
24                 printf("%d", *it2);
25                 r[*it2] = 1;
26             } 
27             else //如果找到了一个最接近的比它大的数
28             {
29                 int val = *it;
30                 if(l[val] == 1)  //如果左节点已经有了
31                 {
32                     set <int>::iterator it2 = --it;
33                     printf("%d", *it2);
34                     r[*it2] = 1;
35                 }
36                 else            //如果左节点没有
37                 {
38                     printf("%d", val);
39                     l[val] = 1;
40                 }
41             }
42             s.insert(a[i]);
43         }
44         printf("
");
45         
46     }
47     return 0;
48 }
原文地址:https://www.cnblogs.com/titicia/p/5506983.html