1233: [Heap]黑匣子
时间限制: 1 Sec 内存限制: 64 MB
提交: 680 解决: 194
[提交][状态][讨论版]题目描述
我们使用黑匣子的一个简单模型。它能存放一个整数序列和一个特别的变量i。在初始时刻,黑匣子为空且i等于0。这个黑匣子执行一系列的命令。有两类命令: (1)ADD(x):把元素x放入黑匣子; (2)GET:i增1的同时,输出黑匣子内所有整数中第i小的数。牢记第i小的数是当黑匣子中的元素以非降序排序后位于第i位的元素(输入数据保证每次GET命令中第i小的数必存在)
输入
输入的第1行只有一个整数n,表示有n条命令. 第2行至第n+1行,每行一条命令.
输出
输出中有若干行内容,每行一个整数,表示相应的get命令的输出.
样例输入
11 ADD(3) GET ADD(1) GET ADD(-4) ADD(2) ADD(8) ADD(-1000) GET GET ADD(2)
样例输出
3 3 1 2
提示
对30%的数据,1≤n≤50000; 对100%的数据,1≤n≤500000; 对所有的数据,ADD命令输入的数在-10000至10000之间;
动态第k小?平衡树乱搞么。。。
查询的第k小中的k是单调递增的,也就是说只要维护前k个数就行了。
怎么维护?沙漏堆呗。
开一个大根堆,一个小跟堆,假设堆是一个三角形的样子,堆顶是某个顶点(算了还是画下图吧)。
对于上面那个大根堆,只要保证它的大小一直是k就行,由于k是单调增的,所以不会涉及到一些神奇的问题。
至于怎么维护大根堆的大小为k,自己想应该能想出来。
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <queue> 7 #include <cmath> 8 #include <vector> 9 #include <map> 10 #include <string> 11 12 using namespace std; 13 14 char s[1000]; 15 16 priority_queue<int> q1; 17 priority_queue<int, vector<int>, greater<int> > q2; 18 19 int n, a, p, pp; 20 21 char get(){ 22 return s[p ++]; 23 } 24 25 void rd(int &x){ 26 x = 0; 27 char c; 28 int f = 1; 29 30 char ret = 0; 31 32 while((c = get() - '0'), (c > 9 || c < 0 || c == '-' - '0')){ 33 if(c == '-' - '0') f = -1; 34 if(!ret && c >= 'A' && c <= 'Z') ret = c; 35 } 36 while((c >= 0 && c <= 9)) (x *= 10) += c, c = get() - '0'; 37 x *= f; 38 } 39 40 int main(){ 41 scanf("%d", &n); 42 while(n --){ 43 scanf("%s", s); 44 p = 0; 45 rd(a); 46 // cout << "A = " << a << endl; 47 if(s[0] == 'A'){ 48 // cout << "DOA" << endl; 49 if(q1.empty() || a < q1.top()){ 50 q1.push(a); 51 }else{ 52 q2.push(a); 53 } 54 }else{ 55 pp ++; 56 while(q1.size() && q1.size() > pp){ 57 q2.push(q1.top()); 58 q1.pop(); 59 } 60 while(q1.size() < pp){ 61 q1.push(q2.top()); 62 q2.pop(); 63 } 64 printf("%d\n", q1.top()); 65 } 66 } 67 }