CF Beta Round #19 D. Points 线段树

仔细看这个题是一个偏序问题  我们对x轴建立线段树   线段树上维护y的最大值  因为每个x都对应多个y  所以我们需要在叶子结点开一个set数组  

对于1,2操作 我们更新即可

对于3操作 我们询问 区间 x+1~inf 这应该算个套路了 然后先询问左子树 保证是大于x的最小x  到了叶子结点 在经过set二分来找y  通过维护y的最大值 我们可以保证复杂度

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
set<int>y[N];
struct Query{
	int op,x,y;
}q[N];
int has[N],tot,mx[N<<2];
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define pa pair<int,int>
void pushup(int id){
	mx[id]=max(mx[id<<1],mx[id<<1|1]);
}
void update(int id,int l,int r,int pos,int val,int op){
	if(l==r){
		if(!op) y[l].insert(val);
		else y[l].erase(val);
		if(y[l].size()==0) mx[id]=-1;
		else
		mx[id]=(*(--y[l].end()));
		return;	
	}
	int mid = l+r>>1;
	if(pos<=mid) update(lson,pos,val,op);
	else update(rson,pos,val,op);
	pushup(id);
}
pa query(int id,int l,int r,int L,int R,int val){
	if(L<=l&&R>=r){
		if(mx[id]<=val) return make_pair(-1,-1);
	}
	if(l==r){
		auto w = y[l].upper_bound(val);
		if(w==y[l].end()) return make_pair(-1,-1);
		else return make_pair(l,*w);
	}
	int mid = l+r>>1;
	pa ret = make_pair(-1,-1);
	if(L<=mid) ret=query(lson,L,R,val);
	if(ret.first!=-1) return ret;
	if(R>mid) ret=query(rson,L,R,val);
	return ret;
}
int main(){
	int n;
	scanf("%d",&n);
	memset(mx,-1,sizeof(mx));
	char str[10];
	for(int i = 1; i <= n; i++){
		scanf("%s%d%d",str,&q[i].x,&q[i].y);
		if(str[0]=='a') q[i].op=0;
		else if(str[0]=='r') q[i].op=1;
		else q[i].op=2;
		has[++tot]=q[i].x;
	}
	sort(has+1,has+1+tot);
	tot=unique(has+1,has+1+tot)-has-1;
	for(int i = 1; i <= n; i++){
		int pos = lower_bound(has+1,has+1+tot,q[i].x)-has;
		if(q[i].op<=1)	update(1,1,tot,pos,q[i].y,q[i].op);
		else{
			if(pos==tot){
				puts("-1");
				continue;
			}
			pa ans = query(1,1,tot,pos+1,tot,q[i].y);
			if(ans.first==-1){
				puts("-1");
			}else{
				printf("%d %d\n",has[ans.first],ans.second);
			}
		}
	}
	return 0;
}
原创文章 85 获赞 103 访问量 2472

猜你喜欢

转载自blog.csdn.net/weixin_43824564/article/details/106149368