[CF1354D] Multiset
Description
维护一个可重集。初始时里面有 (n) 个正整数 ({A_1,A_2,cdots A_n}),它们的值域为 ([1,n])。现在有 (q) 个操作,共有两类:删除排名为 (|k|) 的数字,若不存在排名为 (|k|) 的数字,则忽略这次操作;加入数字 (k),满足 (kin[1,n])。输出任意一个数列中存在的数字或判定集合为空。
Solution
由于只需要输出一个数,我们可以考虑钦定输出最小的那个数。
二分答案,即此时我们确定了最后剩下的最小的数是多少,设为 (mid),那么小于等于 (mid) 的数我们都当做 (0),大于 (mid) 的数我们都当做 (1)。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e+6 + 5;
const int M = 1e+3 + 5;
const int mod1 = 1e+9 + 7;
const int mod2 = 998244353;
#define dbg(x) cerr << #x << ":" << x << endl
void solve()
{
int n, m;
cin >> n >> m;
vector<int> a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
vector<int> b(m);
for (int i = 0; i < m; i++)
cin >> b[i];
int l = 0, r = n, ans = 1e18;
while (l <= r)
{
int mid = (l + r) / 2;
int c[2] = {0, 0};
for (int i : a)
c[i > mid]++;
for (int i : b)
{
if (i > 0)
c[i > mid]++;
else
c[abs(i) > c[0]]--;
c[0] = max(0ll, c[0]);
c[1] = max(0ll, c[1]);
}
if (c[1])
l = mid + 1;
else
r = mid - 1,
ans = min(ans, mid);
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
int t;
t = 1;
while (t--)
{
solve();
}
return 0;
}