思路
就是要你实现一个求第k大数的数据结构,大水题。由于空间比较吃紧,所以使用树状数组来实现。这里也当作记录一个模板。
树状数组求第k大数有 (log_2n) 的实现方法,十分巧妙。
也可以用线段树实现,甚至不用动态开点。只要能一个数组实现就可以。
实现
用贪心的思想,按二进制位从大到小判断。详见代码。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
#define inf 0x3f3f3f3f
int tarr[N];
int n;
int lowbit(int x) {return x & -x;}
void add(int p, int v) {
while(p <= n) {
tarr[p] += v;
p += lowbit(p);
}
}
int query(int p) { //小于等于 //获得第p大的数
int res = 0, cnt = 0;
for(int i = 20; i >= 0; i--) {
if(res + (1 << i) <= n && cnt + tarr[res + (1 << i)] < p) {
cnt += tarr[res + (1 << i)];
res += (1 << i);
}
}
return res + 1;
}
int main() {
ios::sync_with_stdio(false);
int q;
cin >> n >> q;
for(int i = 1; i <= n; i++) {
int v;
cin >> v;
add(v, 1);
}
int cnt = n;
while(q--) {
int v;
cin >> v;
if(v > 0) {
add(v, 1);
cnt++;
} else {
add(query(-v), -1);
cnt--;
}
}
if(!cnt) cout << "0" << endl;
else cout << query(1) << endl;
}