非旋转 treap

其实之前学过一次非旋转 treap,但是全忘光了,今天复习一下. 

洛谷 P3369 【模板】普通平衡树  

code: 

#include <bits/stdc++.h>   
#define N  100006  
#define lson t[x].ls 
#define rson t[x].rs   
#define setIO(s) freopen(s".in","r",stdin)         
using namespace std;       
int root;  
namespace treap
{ 
    int tot; 
    struct node 
    {      
        int val,size,ls,rs,ran;   
    }t[N];
    inline void newnode(int &x,int val) 
    {
        ++tot;   
        t[tot].size=1;
        t[tot].val=val;    
        t[tot].ran=rand();   
        t[tot].ls=t[tot].rs=0;        
        x=tot;   
    }
    inline void pushup(int x) 
    {
        t[x].size=t[lson].size+t[rson].size+1;  
    }
    void split(int x,int &l,int &r,int val)
    {
        if(!x) { l=r=0; return; }       
        if(t[x].val<=val)  l=x, split(t[x].rs,t[l].rs,r,val); 
        else   r=x, split(t[x].ls,l,t[r].ls,val); 
        pushup(x);  
    }
    void merge(int &x,int a,int b) 
    {
        if(!a||!b)  { x=a+b;   return; }        
        if(t[a].ran<t[b].ran)  x=a, merge(t[x].rs,t[a].rs,b); 
        else  x=b, merge(t[x].ls,a,t[b].ls);         
        pushup(x);    
    }      
    void insert(int val) 
    {   
        int x=0,y=0,z=0;    
        newnode(z,val); 
        split(root,x,y,val-1);        
        merge(x,x,z); 
        merge(root,x,y);   
    }
    void del(int val) 
    {
        int x=0,y=0,z=0;      
        split(root,x,y,val);  
        split(x,x,z,val-1);          
        merge(z,t[z].ls,t[z].rs);            
        merge(x,x,z); 
        merge(root,x,y); 
    }               
    void ask_rank(int v) 
    {
        int x=0,y=0;   
        split(root,x,y,v-1);   
        printf("%d\n",t[x].size+1);      
        merge(root,x,y);  
    }
    void ask_num(int x,int kth) 
    {
        while(t[lson].size+1!=kth) 
        {
            if(t[lson].size>=kth)  x=lson; 
            else kth-=(t[lson].size+1),x=rson; 
        } 
        printf("%d\n",t[x].val); 
    }
    void ask_front(int v) 
    {
        int x=0,y=0;   
        split(root,x,y,v-1);  
        ask_num(x,t[x].size);  
        merge(root,x,y);  
    }
    void ask_back(int v) 
    {
        int x=0,y=0;      
        split(root,x,y,v),ask_num(y,1), merge(root,x,y);   
    }
};  
int main() 
{ 
    // setIO("input");       
    int i,j,n;  
    srand(16); 
    scanf("%d",&n);    
    for(i=1;i<=n;++i) 
    {
        int opt,x; 
        scanf("%d%d",&opt,&x);                        
        if(opt==1) treap::insert(x); 
        if(opt==2) treap::del(x);
        if(opt==3) treap::ask_rank(x);     
        if(opt==4) treap::ask_num(root,x); 
        if(opt==5) treap::ask_front(x);
        if(opt==6) treap::ask_back(x);    
    }
    return 0; 
}

 

洛谷P3391 【模板】文艺平衡树  

code: 

#include <bits/stdc++.h>   
#define N 100006   
#define lson t[x].ls 
#define rson t[x].rs  
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;                       
int tot,root; 
struct node 
{
    int ls,rs,val,size,ran,rev; 
}t[N];            
inline void newnode(int &x,int val)  
{ 
    x=++tot; 
    t[x].ls=t[x].rs=0;   
    t[x].val=val; 
    t[x].size=1;  
    t[x].ran=rand();  
    t[x].rev=0; 
}          
inline void pushup(int x)
{ 
    t[x].size=t[lson].size+t[rson].size+1;  
}
void mark(int x) 
{
    swap(lson,rson), t[x].rev^=1; 
}             
inline void pushdown(int x) 
{ 
    if(t[x].rev) 
    {
        if(lson)   mark(lson); 
        if(rson)   mark(rson); 
        t[x].rev=0; 
    }
}                
void split(int x,int &l,int &r,int kth) 
{                
    if(!x) { l=r=0;  return; }      
    pushdown(x); 
    if(t[lson].size+1<=kth) l=x,split(rson,t[l].rs,r,kth-t[lson].size-1);     
    else r=x,split(lson,l,t[r].ls,kth);       
    pushup(x); 
}       
void merge(int &x,int a,int b) 
{   
    if(!a||!b) { x=a+b; return; }     
    pushdown(a),pushdown(b);               
    if(t[a].ran<t[b].ran) x=a, merge(rson,t[a].rs,b);  
    else x=b, merge(lson,a,t[b].ls); 
    pushup(x);   
}    
void build(int &x,int l,int r) 
{
    int mid=(l+r)>>1;  
    newnode(x,mid);    
    if(mid>l)   build(lson,l,mid-1); 
    if(r>mid)   build(rson,mid+1,r);  
    pushup(x);     
} 
void dfs(int x) 
{
    pushdown(x);  
    if(lson)   dfs(lson); 
    printf("%d ",t[x].val); 
    if(rson)   dfs(rson);      
}
int main()  
{ 
    // setIO("input");  
    int i,j,n,m; 
    scanf("%d%d",&n,&m);   
    build(root,1,n);               
    for(i=1;i<=m;++i) 
    {
        int l,r; 
        scanf("%d%d",&l,&r);   
        int x=0,y=0,z=0;   
        split(root,x,y,r);    
        // x : 1->r   y : r+1->n    
        split(x,x,z,l-1);                             
        mark(z);  
        root=0; 
        merge(root,root,x);                 
        merge(root,root,z); 
        merge(root,root,y);       
    }
    dfs(root);  
    return 0; 
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值