zoukankan      html  css  js  c++  java
  • 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
    ",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
    ");  
                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
    ",xx,-*it);   
                }
            }
        }
        return 0;   
    }   
    

      

  • 相关阅读:
    C字符串和C++中string的区别 &amp;&amp;&amp;&amp;C++中int型与string型互相转换
    UML的类图关系分为: 关联、聚合/组合、依赖、泛化(继承)
    STL map详细用法和make_pair函数
    字符串旋转(str.find()---KMP)
    层次遍历二叉树
    图像特征提取三大法宝:HOG特征,LBP特征,Haar特征
    位运算---整数间的转化
    最大公倍数
    单链表的实现
    jsp下Kindeditor环境搭建
  • 原文地址:https://www.cnblogs.com/guangheli/p/11779555.html
Copyright © 2011-2022 走看看