题意
在坐标系中有三种操作
- 增加一个点 ( x , y ) (x,y) (x,y)
- 删除点 ( x , y ) (x,y) (x,y)
- 查询严格在点 ( x , y ) (x,y) (x,y) 右上角的点中,横坐标最小的点,如果有多个点,选择纵坐标最小的那个
题解
先把坐标离散化, s e t [ x ] set[x] set[x] 维护横坐标 x x x 上的点,线段树维护 x x x 轴上区间内最高的 y y y 坐标
#include<iostream>
#include<sstream>
#include<string>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<vector>
#include<stack>
#include <utility>
#include<list>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<iomanip>
#include<time.h>
#include<random>
using namespace std;
#include<ext/pb_ds/priority_queue.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace __gnu_pbds;
#include<ext/rope>
using namespace __gnu_cxx;
#define int long long
#define PI acos(-1.0)
#define eps 1e-9
#define lowbit(a) ((a)&-(a))
const int mod = 1e9+7;
int qpow(int a,int b){
int ans=1;
while(b){
if(b&1)ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
const int INF = 0x3f3f3f3f;
const int N = 1e6+10;
struct point{
string op;
int x,y;
}p[N];
struct node{
int l,r,mid;
int w;
}seg[N];
int lx[N],ly[N],posx,posy;
set<int>s[N];
void pu(int rt){seg[rt].w=max(seg[rt<<1].w,seg[rt<<1|1].w);}
void build(int rt,int l,int r){
int mid=(l+r)>>1;
seg[rt]={l,r,mid,0};
if(l==r){seg[rt].w=-1;s[l].insert(-1);return;}
build(rt<<1,l,mid),build(rt<<1|1,mid+1,r);
pu(rt);
}
void update(int rt,int pos,int val){
if(seg[rt].l==seg[rt].r){seg[rt].w=(*s[pos].rbegin());return;}
if(pos<=seg[rt].mid) update(rt<<1,pos,val);
else update(rt<<1|1,pos,val);
pu(rt);
return;
}
void query(int rt,int val,int l,int r){
if(l>seg[rt].r||r<seg[rt].l)return;
if(seg[rt].w<=val||seg[rt].l>posx)return;
if(seg[rt].l==seg[rt].r){
if(seg[rt].w>val){
posx=min(seg[rt].l,posx);
}
return;
}
if(seg[rt].mid>=l)query(rt<<1,val,l,r);
if(seg[rt].mid<r)query(rt<<1|1,val,l,r);
return;
}
#define endl '\n'
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n; cin>>n;
for(int i=1;i<=n;i++){
cin>>p[i].op>>p[i].x>>p[i].y;
lx[i]=p[i].x,ly[i]=p[i].y;
}
sort(lx+1,lx+1+n); sort(ly+1,ly+1+n);
int cx=unique(lx+1,lx+1+n)-lx-1,cy=unique(ly+1,ly+1+n)-ly-1;
build(1,1,cx);
for(int i=1;i<=n;i++){
int px=lower_bound(lx+1,lx+1+cx,p[i].x)-lx,py=lower_bound(ly+1,ly+1+cy,p[i].y)-ly;
if(p[i].op=="add"){
s[px].insert(py);
update(1,px,py);
}
if(p[i].op=="remove"){
s[px].erase(py);
update(1,px,py);
}
if(p[i].op=="find"){
posx=INF;
query(1,py,px+1,cx);
if(posx==INF)cout<<-1<<endl;
else{
set<int>::iterator it=s[posx].upper_bound(py);
posy=*it;
cout<<lx[posx]<<" "<<ly[posy]<<endl;
}
}
}
}