题目大意:将一个点加入或者删除,查找一个严格大于点。
这边应用到了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);
}
}
}