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;
}

浙公网安备 33010602011771号