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("\n"); 45 46 } 47 return 0; 48 }