Problem - 1354D - Codeforces
我被卡了:
这道题看到multiset我还真写multiset,结果内存超限。
当然能想到想同的数存到一块,所以用了map,结果还超,诶呦:

set肯定比map大滴,这里可能刚超就结束了,事实上可能占用更大。
思路:
本题是得用树状数组或者线段树存出现次数做,而且内存足够多。

我是用的类构造的线段树。
初始一个1e6的数组,构造里有1e6的这个数组和树状数组,比3e6大,粗算一下吧,4e6 * 4字节 = 16e6 ,也就是16MB,也不超28MB。
————
存出现次数,树状数组记录的前缀和,所以可以二分找到第几个数。
代码:
这个类板子就是我的树状数组1
template<class T>
class BIT//Binary Indexed Tree
{
public:
	ll n;//a的大小
	vector<T>a;//原数组
	vector<T>c;//树状数组
	ll lowbit(ll a)
	{
		return a & -a;
	}
	T getsum(ll i)
	{
		T sum = 0;
		while (i > 0)
		{
			sum += c[i];
			i -= lowbit(i);
		}
		return sum;
	}
	void add(ll i, T v)
	{
		while (i <= n)
		{
			c[i] += v;
			i = i + lowbit(i);
		}
	}
	BIT(vector<T>_a)
	{
		a = _a;
		n = a.size() - 1;
		c = vector<T>(n + 1);
		//直接把树建好
		for (ll i = 1; i <= n; i++)
		{
			add(i, a[i]);
		}
	}
};
void solve(int casen)
{
	int n, m;
	cin >> n >> m;
	vector<int>arr(1000002);
	BIT<int> demo(arr);
	for (int i = 1; i <= n; i++)
	{
		int tmp;
		cin >> tmp;
		demo.add(tmp, 1);
	}
	for (int i = 1; i <= m; i++)
	{
		int tmp;
		cin >> tmp;
		if (tmp < 0)
		{
			tmp = -tmp;
			//二分找第tmp个
			int l = 1, r = 1000000;
			while (l < r)
			{
				int mid = l + (r - l) / 2;
				if (demo.getsum(mid) >= tmp)
					r = mid;
				else
					l = mid + 1;
			}
			demo.add(l, -1);//有人给tmp减
		}
		else
		{
			demo.add(tmp, 1);
		}
	}
	int l = 1, r = 1000000;
	if (demo.getsum(1000000) == 0)
	{
		cout << 0;
		return;
	}
	while (l < r)
	{
		int mid = l + (r - l) / 2;
		if (demo.getsum(mid) > 0)
		{
			r = mid;
		}
		else
			l = mid + 1;
	}
	cout << l;
}
signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int t = 1;
	//cin >> t;
	for (int i = 1; i <= t; i++)
	{
		solve(i);
	}
	return 0;
}


















