每个线段树节点不用开 set,直接存最大的 y 坐标就好了,足够二分的时候用了,只有底层节点才需要开 set。
这样一来,代码的复杂度虽然是两个 log 的,但是能过。
然后写出来的代码可能是这样的。
#include<bits/stdc++.h>
using namespace std;
const int maxn=200004;
char op[maxn<<2];
int n,recx[maxn],recy[maxn],mpx[maxn*2],mpy[maxn*2],maxy[maxn<<3];
vector< int > cpy;
set< int > mem[maxn<<3];
void add(int l,int r,int ver,int x,int y){
if(l==r){
mem[ver].insert(y);
maxy[ver]=max(maxy[ver],y);
return ;
}
int mid=(l+r)>>1,lver=ver<<1,rver=ver<<1|1;
if(x<=mid)
add(l,mid,lver,x,y);
else
add(mid+1,r,rver,x,y);
maxy[ver]=max(maxy[lver],maxy[rver]);
}
void rmv(int l,int r,int ver,int x,int y){
if(!ver)
return ;
if(l==r){
mem[ver].erase(y);
if(mem[ver].size()){
auto it=mem[ver].end();
--it;
maxy[ver]=*it;
}
else
maxy[ver]=0;
return ;
}
int mid=(l+r)>>1,lver=ver<<1,rver=ver<<1|1;
if(x<=mid)
rmv(l,mid,lver,x,y);
else
rmv(mid+1,r,rver,x,y);
maxy[ver]=max(maxy[lver],maxy[rver]);
}
int check(int l,int r,int ver,int start,int end,int y){
if(!ver)
return 0;
if(start<=l&&r<=end)
return (maxy[ver]>y)?1:0;
int mid=(l+r)>>1,lver=ver<<1,rver=ver<<1|1,ret=0;
if(start<=mid&&maxy[lver]>y)
ret|=check(l,mid,lver,start,end,y);
if(end>mid&&maxy[rver]>y)
ret|=check(mid+1,r,rver,start,end,y);
return ret;
}
pair<int,int> binsearch(int l,int r,int ver,int x,int y){
if(!ver)
return make_pair(-1,-1);
if(l==r){
auto it=mem[ver].upper_bound(y);
if(it==mem[ver].end())
return make_pair(-1,-1);
else
return make_pair(l,*it);
}
int mid=(l+r)>>1,lver=ver<<1,rver=ver<<1|1;
if(check(l,r,ver,x+1,mid,y))
return binsearch(l,mid,lver,x,y);
else
return binsearch(mid+1,r,rver,x,y);
}
int main(){
readi(n);
for(int i=1;i<=n;i++){
readstr(op+maxn),readi(recx[i]),readi(recy[i]);
cpy.push_back(recx[i]);
op[i]=op[maxn];
}
sort(cpy.begin(),cpy.end());
int sz=unique(cpy.begin(),cpy.end())-cpy.begin();
for(int i=1;i<=n;i++){
int px=lower_bound(cpy.begin(),cpy.begin()+sz,recx[i])-cpy.begin()+1;
mpx[px]=recx[i],recx[i]=px;
}
for(int i=1;i<=n;i++){
if(op[i]=='a')
add(1,sz+1,1,recx[i],recy[i]);
if(op[i]=='r')
rmv(1,sz+1,1,recx[i],recy[i]);
if(op[i]=='f'){
auto res=binsearch(1,sz+1,1,recx[i],recy[i]);
if(res.first==-1)
puts("-1");
else{
write(mpx[res.first]),putchar(' '),write(res.second);
puts("");
}
}
}
return 0;
}
如果你觉得这是 tlqtj 就举报吧,反正我只是想给后人一点帮助,同时给自己留个纪念(