照着题解一行一行对的,线段树分裂10pts求调
查看原帖
照着题解一行一行对的,线段树分裂10pts求调
965685
yyrwlj楼主2024/10/4 10:20
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 200005, inf = 2e5;
struct Tree{
	int ls, rs;
	LL v;
}tr[N << 5];
int sta[N << 5], top, idx = 1;
int rt[N];
inline int newnode()
{
	return top ? sta[top --] : ++ idx;
}
inline void remove(int u)
{
	tr[u] = {0, 0, 0};
	sta[++ top] = u;
}
void update(int& u,int l,int r,int p,int x)
{
	if (!u)
		u = newnode();
	tr[u].v += x;
	if (l == r)
		return;
	int mid = (l + r) >> 1;
	if (p <= mid)
		update(tr[u].ls, l, mid, p, x);
	else
		update(tr[u].rs, mid + 1, r, p, x);
}
LL query(int u,int l,int r,int L,int R)
{
	if (!u || l>R || L>r)
		return 0;
	if (L <= l && r <= R)
		return tr[u].v;
	int mid = (l + r) >> 1;
	LL res = 0;
	if (L <= mid)
		res = query(tr[u].ls, l, mid, L, R);
	if (mid < R)
		res += query(tr[u].rs, mid + 1, r, L, R);
	return res;
}
int get_k(int u,int l,int r,LL k)
{
	if (tr[u].v < k)
		return -1;
	if (l == r)
		return l;
	int mid = (l + r) >> 1;
	if (tr[tr[u].ls].v >= k)
		return get_k(tr[u].ls, l, mid, k);
	return get_k(tr[u].rs, mid + 1, r, k - tr[tr[u].ls].v);
}
int merge(int x,int y)
{
	if (!x || !y)
		return x | y;
	tr[x].v += tr[y].v;
	tr[x].ls = merge(tr[x].ls, tr[y].ls);
	tr[x].rs = merge(tr[x].rs, tr[y].rs);
	remove(y);
	return x;
}
void split(int x,int& y,LL k)
{
	if (!x)
		return;
	y = newnode();
	LL v = tr[tr[x].ls].v;
	if (k > v)
		split(tr[x].rs, tr[y].rs, k - v);
	else
		swap(tr[x].rs, tr[y].rs);
	if (k < v)
		split(tr[x].ls, tr[y].ls, k);
	tr[y].v = tr[x].v - k;
	tr[x].v = k;
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	int n, m;
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		update(rt[1], 1, inf, i, x);
	}
	int tot = 1;
	while (m--)
	{
		int op, p, x;
		cin>>op>>p>>x;
		if (op == 0)
		{
			LL y;
			cin>>y;
			tot ++;
			LL s1 = query(rt[p], 1, inf, 1, y), s2 = query(rt[p], 1, inf, x, y);
			split(rt[p], rt[tot], s1 - s2);
			split(rt[tot], op, s2);
			rt[x] = merge(rt[x], op);
		}
		else if (op == 1)
			rt[p] = merge(rt[p], rt[x]);
		else if (op == 2)
		{
			LL q;
			cin>>q;
			update(rt[p], 1, inf, q, x);
		}
		else if (op == 3)
		{
			LL y;
			cin>>y;
			cout<<query(rt[p], 1, inf, x, y)<<'\n';
		}
		else
			cout<<get_k(rt[p], 1, inf, x)<<'\n';
		
	}
	return 0;
}
2024/10/4 10:20
加载中...