CF19D Points 平衡树
题意:支持插入/删除点 $(x,y)$,查询一个点右上方横坐标与之最接近的点坐标.
我们可以对于每一个操作过的横坐标都开一个 $set$,然后再开一个平衡树,维护每个横坐标上最大的纵坐标.
然后查询点 $(x,y)$ 时就在平衡树查一下第一个横坐标大于 $x$,且最大值大于 $y$ 的就行了.
$splay$ 中有一些细节需要注意一下.
#include <set> #include <map> #include <cstdio> #include <algorithm> #define N 200005 #define inf 1200000005 #define lson p[x].ch[0] #define rson p[x].ch[1] #define setIO(s) freopen(s".in","r",stdin) using namespace std; int tot,cnt,pp,root; set<int>S[N]; map<int,int>idx,sp; set<int>::iterator it; struct data { int ch[2],f,maxx,val,id,size; }p[N]; int newnode() { return ++tot; } int get(int x) { return p[p[x].f].ch[1]==x; } void pushup(int x) { p[x].maxx=p[x].val; p[x].maxx=max(p[x].val,max(p[lson].maxx,p[rson].maxx)); p[x].size=p[lson].size+p[rson].size+1; } void rotate(int x) { int old=p[x].f,fold=p[old].f,which=get(x); p[old].ch[which]=p[x].ch[which^1],p[p[old].ch[which]].f=old; p[x].ch[which^1]=old,p[old].f=x,p[x].f=fold; if(fold) p[fold].ch[p[fold].ch[1]==old]=x; pushup(old),pushup(x); } void splay(int x,int &tar) { int fa,u=p[tar].f; for(;(fa=p[x].f)!=u;rotate(x)) if(p[fa].f!=u) rotate(get(fa)==get(x)?fa:x); tar=x; } void insert(int &x,int ff,int id,int v) { if(!x) { x=newnode(); p[x].id=id,p[x].val=v; if(!sp[id]) sp[id]=++pp; p[x].f=ff; pushup(x); } else { insert(p[x].ch[id>p[x].id],x,id,v); pushup(x); } } int getr(int x) { while(rson) x=rson; return x; } int getpre(int v) { int x=root,pre=root; while(x) { if(p[x].id<=v) pre=x, x=rson; else x=lson; } return pre; } int find(int x,int d) { if(p[lson].maxx>d) return find(lson,d); else if(p[x].val>d) return p[x].id; else return find(rson,d); } int main() { // setIO("input"); int i,j,n; scanf("%d",&n); p[0].maxx=-inf; insert(root,0,-inf,-inf); insert(root,0, inf,-inf); for(i=1;i<=n;++i) { char str[10]; scanf("%s",str); if(str[0]=='a') { int x,y; scanf("%d%d",&x,&y); if(!idx[x]) idx[x]=++cnt; S[idx[x]].insert(-y); int xx=-(*S[idx[x]].begin()); if(sp[x]) { splay(sp[x], root); p[root].val=xx; pushup(root); } else { insert(root,0,x,y); splay(tot,root); // printf("%d\n",p[root].ch[1]); } } if(str[0]=='r') { int x,y; scanf("%d%d",&x,&y); S[idx[x]].erase(-y); if(S[idx[x]].empty()) { splay(sp[x],root); int L=getr(p[root].ch[0]); int R=p[root].ch[1]; splay(L,p[root].ch[0]); p[L].f=0, p[L].ch[1]=R, p[R].f=root=L; pushup(L); idx[x]=sp[x]=0; } else { splay(sp[x],root); p[root].val=-(*S[idx[x]].begin()); pushup(root); } } if(str[0]=='f') { int x,y; scanf("%d%d",&x,&y); int L=getpre(x); splay(L,root); if(p[p[root].ch[1]].maxx<=y) printf("-1\n"); else { int R=p[root].ch[1]; int xx=find(R,y); int yy=idx[xx]; it=S[yy].lower_bound(-y); if(it==S[yy].end()) it--; while(*it>=-y) it--; printf("%d %d\n",xx,-*it); } } } return 0; }