【CodeForces】 19D Points(线段树|单点更新)

本文介绍了一种结合set容器与线段树的数据结构优化方法,用于解决动态点集维护与查询问题。通过自动排序及高效增删操作,实现快速查找严格大于目标值的元素。文中详细展示了具体实现代码,包括初始化、更新与查询等核心步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:将一个点加入或者删除,查找一个严格大于点。

这边应用到了set容器,自动排序,以及方便的加入和删除。

set a;

a.insert(x);加入这个元素

a.erase(x);删除这个元素

*(--a.end())访问最后一个元素

*(a.upper_bound(x))查找一个大于x的数

sum存的是最大的y

其他的就跟单点更新的线段树一样了

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<set>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAX 220000
#define ls rt<<1
#define rs ls|1
#define m (l+r)>>1

int sum[MAX << 2];
int pos[MAX];
set<int>y[MAX];
struct
{
	char str[10];
	int x, y;
}tg[MAX];
void uprt(int rt)
{
	sum[rt] = max(sum[ls], sum[rs]);
}
void build(int l, int r, int rt)
{
	if (l == r)
	{
		sum[rt] =-1;
		return;
	}
	int mid = m;
	build(l, mid, ls);
	build(mid + 1, r, rs);
	uprt(rt);
}

void updata(int p, int l, int r, int rt)
{
	if (l == r)
	{
		if (!y[p].empty())
			sum[rt] = *(--y[p].end());
		else
			sum[rt] = -1;
		return;
	}
	int mid = m;
	if (p <= mid)
		updata(p, l, mid, ls);
	else
		updata(p, mid + 1, r, rs);
	uprt(rt);
}

int query(int L, int p, int l, int r, int rt)
{
	if (sum[rt]<p)return -1;//防止只有一个坐标的时候
	if (l == r)
		return l;
	int ans = -1;
	int mid = m;
	if (sum[ls] > p&&mid > L)
		ans = query(L, p, l, mid, ls);
	if (ans == -1 && sum[rs] > p&&r > L)
		ans = query(L, p, mid + 1, r, rs);
	return ans;
}
int main()
{
	int n;
	scanf("%d%*c", &n);
	for (int i = 0; i < n; i++)
	{
		scanf("%s%d%d", tg[i].str, &tg[i].x, &tg[i].y);
		pos[i] = tg[i].x;
	}
	sort(pos, pos + n);
	int cnt = unique(pos, pos + n)-pos;
	build(0, cnt - 1, 1);
	for (int i = 0; i < n; i++)
	{
		int cur = lower_bound(pos, pos + cnt, tg[i].x) - pos;
		if (tg[i].str[0] == 'a')
		{
			y[cur].insert(tg[i].y);
			updata(cur, 0, cnt - 1, 1);
		}
		else
		if (tg[i].str[0] == 'f')
		{
			cur = query(cur, tg[i].y, 0, cnt - 1, 1);
			if (cur == -1)
				puts("-1");
			else
				printf("%d %d\n", pos[cur], *y[cur].upper_bound(tg[i].y));
		}
		else
		{
			y[cur].erase(tg[i].y);
			updata(cur, 0, cnt - 1, 1);
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值