CF19D. Points

发布时间 2023-06-19 11:12:26作者: xx019

感觉不难啊,为什么是 *2800 捏。

先离散化。对每个横坐标开一个 set 存点,插入删除就能做了。查询的时候线段树二分就行了。

更具体地,我们维护区间内纵坐标的最大值,在二分的时候能左就左,不能左就右。

注意这里的右上角是严格大于。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define mk make_pair
#define fi first
#define se second
using namespace std;
typedef pair<int,int>pii;
const int inf=1e18;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
char s[105];
struct Que{
	int op,x,y;
}q[200005];
struct segtree{
	#define ls p<<1
	#define rs p<<1|1
	#define lson l,mid,ls
	#define rson mid+1,r,rs
	struct Node{
		multiset<int>s;
		int ma;
	}c[800005];
	void pushup(int p){
		c[p].ma=max(c[ls].ma,c[rs].ma);  
	}
	void build(int l,int r,int p){
		if(l==r){c[p].s.clear();c[p].ma=-inf;return;}
		int mid=(l+r)>>1;
		build(lson),build(rson);
		pushup(p);
	}
	void update(int l,int r,int p,int x,int y,int op){
		if(l==r){
			if(op==1)c[p].s.insert(y);
			else c[p].s.erase(c[p].s.find(y));
			if(c[p].s.empty())c[p].ma=-inf;
			else c[p].ma=*c[p].s.rbegin();
			return;
		}
		int mid=(l+r)>>1;
		if(x<=mid)update(lson,x,y,op);
		else update(rson,x,y,op);
		pushup(p);
	}
	pii ask(int l,int r,int p,int y){
		if(c[p].ma<y)return mk(inf,inf);
		if(l==r)return mk(l,(*c[p].s.lower_bound(y)));
		int mid=(l+r)>>1;
		if(c[ls].ma>=y)return ask(lson,y); 
		else return ask(rson,y);
	}
	pii find(int l,int r,int p,int L,int R,int y){
		if(L>R)return mk(inf,inf);
		if(L<=l&&r<=R)return ask(l,r,p,y);
		int mid=(l+r)>>1;pii res=mk(inf,inf);
		if(L<=mid)res=min(res,find(lson,L,R,y));
		if(R>mid)res=min(res,find(rson,L,R,y));
		return res;
	}
	#undef ls
	#undef rs
	#undef lson
	#undef rson
}Tr;
int bx[200005],by[200005];
signed main(){
	int n=read();
	for(int i=1,op,x,y;i<=n;i++){
		scanf("%s",s);x=read(),y=read();
		if(s[0]=='a')op=1;
		else if(s[0]=='r')op=2;
		else op=3;
		q[i]=(Que){op,x,y};
	}
	int tx=0,ty=0;
	for(int i=1;i<=n;i++){
		bx[++tx]=q[i].x;
	}
	sort(bx+1,bx+tx+1);tx=unique(bx+1,bx+tx+1)-bx-1;
	for(int i=1;i<=n;i++){
		q[i].x=lower_bound(bx+1,bx+tx+1,q[i].x)-bx;
	}
	for(int i=1;i<=n;i++){
		by[++ty]=q[i].y;
	}
	sort(by+1,by+ty+1);ty=unique(by+1,by+ty+1)-by-1;
	for(int i=1;i<=n;i++){
		q[i].y=lower_bound(by+1,by+ty+1,q[i].y)-by;
	}
	Tr.build(1,tx,1);
	for(int i=1;i<=n;i++){
		int op=q[i].op,x=q[i].x,y=q[i].y;
		if(op==3){
			pii res=Tr.find(1,tx,1,x+1,tx,y+1);
			if(res==mk(inf,inf))puts("-1");
			else printf("%lld %lld\n",bx[res.fi],by[res.se]);
		}
		else{
			Tr.update(1,tx,1,x,y,op);
		}
	}
	return 0;
}