题解 CF1354D 【Multiset】
楼上神犇用的都是 我听都没听过的东西。作为一个蒟蒻,只会用最简单的分块做。
时间复杂度插入跑得飞快 勉强能过qwq。
不了解分块的童鞋可以先移步至 分块大法,当然这题并不需要那么多操作,只需了解基本概念即可。
题目数据十分愉快地把
记
详见代码
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000005
int n, q;
int num[maxn], fa[1005];
int main() {
cin.tie(0);
ios::sync_with_stdio(false);
cin >> n >> q;
int mx = 0; //记录出现的最大值,便于最后循环结束的判断,也可以不用。
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
num[x]++; //桶中有的数+1
fa[(x - 1) / 1000]++; //属于的块里有的数+1
mx = max(mx, x);
}
while (q--) {
int k;
cin >> k;
if (k > 0) {
//插入操作 同读入
num[k]++;
fa[(k - 1) / 1000]++;
mx = max(mx, k);
}
else {
//删除操作
k = -k; //别忘了k是负数
//找第k个数属于第几块
int index = 0;
while (k > fa[index]) {
k -= fa[index++];
}
// 此时已找到第k个数属于第index块,只需遍历这一块即可
for (int i = index * 1000 + 1; i < index * 1000 + 1 + 1000; i++) {
//找第k个数是多少
if (k > num[i]) {
k -= num[i];
}
else {
//找到了第k个数
num[i]--; //桶-1
fa[(i - 1) / 1000]--; //属于的块里有的数-1
break;
}
}
}
}
//找到数字就输出,没找到输出0。
for (int i = 1; i <= mx; i++) {
if (num[i]) {
cout << i;
return 0;
}
}
cout << 0;
return 0;
}