首页 > 代码库 > Codeforces 19D Points 线段树+set

Codeforces 19D Points 线段树+set

题目链接:点击打开链接

线段树维护y值大于val的最小x值

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream>
#include <map>
#include <set>
#include <math.h>
using namespace std;
#define inf 1000000010
#define ll int
#define N 200005
#define L(x) (x<<1)
#define R(x) (x<<1|1)
inline ll Mid(ll a,ll b){return (a+b)>>1;}
ll n;
struct node{
	ll x,y;
	node(ll a=0,ll b=0):x(a),y(b){}
	bool operator<(const node &a) const{
		if(a.x==x)
			return a.y>y;
		return a.x>x;
	}
	ll op;
}in[N];
set<node>myset;
set<node>::iterator p;
struct Edge{
	int l, r, id;
	int maxx, lval;
	set<ll>st;
}tree[N<<4];
set<ll>::iterator pp;
set<ll>lisan;
void build(int l,int r,int id){
	tree[id].l =l ,tree[id].r =r;
	tree[id].maxx = tree[id].lval = -1;
	tree[id].st.clear();
	tree[id].st.insert(-1);
	if(l==r)return ;
	int mid = Mid(l,r);
	build(l,mid,L(id));
	build(mid+1,r,R(id));
}
void updata(ll pos, ll id, ll val, ll o){ // o = 1表示插入
	if(tree[id].l== tree[id].r) {
		if(o==1){
			tree[id].st.insert(val);
			tree[id].lval = tree[id].maxx = max(tree[id].maxx,val);			
			return ;
		}
		else tree[id].st.erase(val);
		pp = tree[id].st.end(); pp--;
		tree[id].lval = tree[id].maxx = *pp;
		return;
	}
	ll mid = Mid(tree[id].l,tree[id].r);
	if(mid<pos)updata(pos,R(id),val,o);
	else updata(pos, L(id),val,o);
	tree[id].lval = tree[L(id)].lval;
	tree[id].maxx = max(tree[L(id)].maxx, tree[R(id)].maxx);
}
ll query(ll l, ll r, ll id, ll val){
	if(l <=tree[id].l && tree[id].r<=r) {
		if(tree[id].maxx <= val)return -1;
		if(tree[id].lval >val)return tree[id].l;
	}
	ll mid = Mid(tree[id].l,tree[id].r);
	if(mid<l)return query(l,r,R(id),val);
	else if(r<=mid)return query(l,r,L(id),val);
	ll ans = query(l,mid,L(id),val);
	if(ans!=-1)return ans;
	return query(mid+1,r,R(id),val);
}
ll pos[N<<1];
map<ll,ll>mp;
int main(){
	ll x,y;
	while(~scanf("%d",&n)) {
		myset.clear();
		mp.clear();
		lisan.clear();
		for(ll i = 0; i < n; i++) {
			char s[10];scanf("%s",s);
			scanf("%d %d",&in[i].x,&in[i].y);
			lisan.insert(in[i].x);
			if(s[0]=='a')in[i].op = 1;
			else if(s[0]=='r')in[i].op=2;
			else in[i].op = 3;
		}
		ll siz = 1;
		for(pp=lisan.begin(); pp!=lisan.end(); pp++) {
			pos[siz] = *pp;
			mp.insert(pair<ll,ll>(*pp,siz));
			siz++;
		}
		for(ll i = 0; i < n; i++)in[i].x = mp.find(in[i].x)->second;
		build(1,siz,1);
		for(ll i = 0; i < n; i++){
			x = in[i].x, y = in[i].y;
			if(in[i].op == 1){
				myset.insert(node(pos[x],y));
				updata(in[i].x,1,in[i].y,1);
			}
			else if(in[i].op == 2){
				myset.erase(node(pos[x],y));
				updata(in[i].x,1,in[i].y,0);
			}
			else {
				ll he = query(in[i].x+1,siz,1,in[i].y);
				if(he==-1){puts("-1");continue;}
				printf("%d %d\n",pos[he],myset.lower_bound(node(pos[he],in[i].y+1))->y);
			}
		}
	}
	return 0;
}