20pts有无董哥帮我看看权值线段树错在哪捏
查看原帖
20pts有无董哥帮我看看权值线段树错在哪捏
1219010
shadow_leader楼主2025/1/31 10:55
#include<iostream>
#include<set>
#include<cmath>
using namespace std;

const int N = 1e6 + 10;
const int max_val = 1e6 + 10;

int tr[4 * N],cnt=0,tr2[4*N],ans1,ans2;

set<int>s;

void push_up(int p)
{
	tr[p] = tr[2 * p + 1] + tr[2 * p];
	tr2[p] = tr2[2 * p + 1] + tr2[2 * p];
}

void insert(int p, int l, int r, int k, int val)//插入
{
	if (l == r)
	{
		if (val > 0)
			tr[p]++;
		else
			tr[p]--;
		tr2[p] += val;
		return;
	}
	int mid = (l + r) >> 1;
	if (k <= mid)insert(2 * p, l, mid, k, val);
	else insert(2 * p + 1, mid + 1, r, k, val);
	push_up(p);
}

int kth(int p, int l, int r, int k)//	求第k个数大小
{
	if (l == r)return l;
	int mid = (l + r) >> 1;
	if (k <= tr[2 * p])return kth(2 * p, l, mid, k);
	return kth(2 * p + 1, mid + 1, r, k - tr[2 * p]);
}

int rth(int p, int l, int r, int x)//求x的序号
{
	if (l == r)return 1;
	int mid = (l + r) >> 1;
	if (x <= mid)return rth(2 * p, l, mid, x);
	return rth(2 * p + 1, mid + 1, r, x) + tr[2 * p];
}
int find(int p, int l, int r, int x, int y)//查找美丽值的和
{
	if (x <= l && r <= y)return tr2[p];
	int mid = (l + r) >> 1,ans=0;
	if (x <= mid)ans += find(2 * p, l, mid, x, y);
	if (y > mid)ans += find(2 * p + 1, mid + 1, r, x, y);
	return ans;
}
int main()
{
	int op,w,c;	
	while (1)
	{
		cin >> op;

		if (op == 1)
		{
			cin >> w >> c;
			int step = s.size();
			s.insert(c);
			if (s.size() != step)
			{
				insert(1, 1, max_val, c,w);
				ans1 += c;
				cnt++;
			}

		}
		else if (op == 2&&cnt>0)
		{
			int x = kth(1, 1, max_val,cnt);
			int y = find(1, 1, max_val, x, x);
			ans1 -= x;
			insert(1, 1, max_val, x, -y);
			cnt--;
		}
		else if(op==3&&cnt>0)
		{
			int x = kth(1, 1, max_val,1);
			int y = find(1, 1, max_val, x, x);
			insert(1, 1, max_val, x, -y);
			ans1 -= x;
			cnt--;
		}
		else if(op==-1)
		{
			cout<<find(1, 1, max_val, 1,max_val)<<" "<<ans1 << endl;
			break;
		}
	}
}
2025/1/31 10:55
加载中...