[CF1354D] Multiset

Description

维护一个可重集。初始时里面有 \(n\) 个正整数 \(\{A_1,A_2,\cdots A_n\}\),它们的值域为 \([1,n]\)。现在有 \(q\) 个操作,共有两类:删除排名为 \(|k|\) 的数字,若不存在排名为 \(|k|\) 的数字,则忽略这次操作;加入数字 \(k\),满足 \(k\in[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;
}

相关文章:

  • 2021-12-01
  • 2021-07-26
  • 2021-08-27
  • 2021-09-03
  • 2021-07-30
  • 2022-12-23
  • 2021-08-13
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-29
  • 2021-12-12
  • 2022-12-23
  • 2022-01-04
相关资源
相似解决方案