洛谷堆P1801 黑匣子_NOI导刊2010提高(06)
Posted DEVILK
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷堆P1801 黑匣子_NOI导刊2010提高(06)相关的知识,希望对你有一定的参考价值。
【题目描述:】
Black Box是一种原始的数据库。它可以储存一个整数数组,还有一个特别的变量i。最开始的时候Black Box是空的.而i等于0。这个Black Box要处理一串命令。
命令只有两种:
ADD(x):把x元素放进BlackBox;
GET:i加1,然后输出Blackhox中第i小的数。
记住:第i小的数,就是Black Box里的数的按从小到大的顺序排序后的第i个元素。
现在要求找出对于给定的命令串的最好的处理方法。ADD和GET命令分别最多200000个。现在用两个整数数组来表示命令串:
1.A(1),A(2),…A(M):一串将要被放进Black Box的元素。每个数都是绝对值不超过2000000000的整数,M<=200000。例如上面的例子就是A=(3,1,一4,2,8,-1000,2)。
2.u(1),u(2),…u(N):表示第u(j)个元素被放进了Black Box里后就出现一个GET命令。例如上面的例子中u=(l,2,6,6)。输入数据不用判错。
【输入格式:】
第一行,两个整数,M,N。
第二行,M个整数,表示A(l)…A(M)。
第三行,N个整数,表示u(l)…u(N)。
【输出格式:】
输出Black Box根据命令串所得出的输出串,一个数字一行。
输入样例#1: 7 4 3 1 -4 2 8 -1000 2 1 2 6 6 输出样例#1: 3 3 1 2
【算法分析:】
开两个堆,一个大根堆,一个小根堆,类似于“中位数”那道题
把每一个要求加入Black_Box的元素放入小根堆,然后把堆顶元素弹出后放到大根堆
这时如果小根堆的堆顶比大根堆的堆顶小,就交换两个堆的堆顶元素,
直到小根堆的堆顶比大根堆的堆顶元素大,或者小根堆已空
这时大根堆的堆顶元素就是第i小的值
【代码:】
1 //黑匣子_NOI导刊2010提高 2 #include<iostream> 3 #include<cstdio> 4 using namespace std; 5 6 const int MAXN = 200000 + 1; 7 8 int n, m, a[MAXN], u[MAXN]; 9 10 int h1_size, h2_size; 11 int h1[MAXN], h2[MAXN]; 12 13 void push1(int x) { 14 h1[++h1_size] = x; 15 int now = h1_size, next; 16 while(now > 1) { 17 next = now >> 1; 18 if(h1[now] < h1[next]) 19 swap(h1[now], h1[next]); 20 else break; 21 now = next; 22 } 23 } 24 int pop1() { 25 int ret = h1[1]; 26 h1[1] = h1[h1_size--]; 27 int now = 1, next; 28 while((now << 1) <= h1_size) { 29 next = now << 1; 30 if(next < h1_size && h1[next|1] < h1[next]) next |= 1; 31 if(h1[now] > h1[next]) 32 swap(h1[now], h1[next]); 33 else break; 34 now = next; 35 } 36 return ret; 37 } 38 39 void push2(int x) { 40 h2[++h2_size] = x; 41 int now = h2_size, next; 42 while(now > 1) { 43 next = now >> 1; 44 if(h2[now] > h2[next]) 45 swap(h2[now], h2[next]); 46 else break; 47 now = next; 48 } 49 } 50 int pop2() { 51 int ret = h2[1]; 52 h2[1] = h2[h2_size--]; 53 int now = 1, next; 54 while((now << 1) <= h2_size) { 55 next = now << 1; 56 if(next < h2_size && h2[next|1] > h2[next]) next |= 1; 57 if(h2[now] < h2[next]) 58 swap(h2[now], h2[next]); 59 else break; 60 now = next; 61 } 62 return ret; 63 } 64 65 int read() { 66 int x = 0, f = 1; 67 char ch = getchar(); 68 while(ch < ‘0‘ || ch > ‘9‘) { 69 if(ch == ‘-‘) f = -1; 70 ch = getchar(); 71 } 72 while(ch >= ‘0‘ && ch <= ‘9‘) { 73 x = (x << 3) + (x << 1) + ch - 48; 74 ch = getchar(); 75 } 76 return x * f; 77 } 78 void write(int x) { 79 if(x < 0) { 80 putchar(‘-‘); 81 x = -x; 82 } 83 if(x > 9) write(x / 10); 84 putchar(x % 10 + 48); 85 } 86 87 int main() { 88 n = read(), m = read(); 89 for(int i = 1; i <= n; i++) a[i] = read(); 90 for(int i = 1; i <= m; i++) u[i] = read(); 91 for(int i = 1; i <= m; i++) { 92 for(int j = u[i - 1] + 1; j <= u[i]; j++) push1(a[j]); 93 push2(pop1()); 94 while(h1_size > 0 && h1[1] < h2[1]) { 95 int x1 = pop1(), x2 = pop2(); 96 push1(x2), push2(x1); 97 } 98 write(h2[1]); 99 putchar(‘\n‘); 100 } 101 }
以上是关于洛谷堆P1801 黑匣子_NOI导刊2010提高(06)的主要内容,如果未能解决你的问题,请参考以下文章