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

  

posted @ 2019-11-01 20:53  EM-LGH  阅读(171)  评论(0编辑  收藏  举报