1. 程式人生 > 實用技巧 >結構體Splay平衡樹板子

結構體Splay平衡樹板子

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
const int INF = 1e9;

class Splay{
#define root t[0].son[1]
private:
    struct node{
        int son[2];
        int val,father;
        int size,cnt;
    }t[maxn];
    int n,tot;
    
    void pushup(int x){
        if(x)t[x].size=t[x].cnt+t[t[x].son[0
]].size+t[t[x].son[1]].size; } int identfy(int x){ return t[t[x].father].son[1]==x; } void connect(int son,int father,int lr){ t[son].father=father; t[father].son[lr]=son; } void rotate(int x){ int f=t[x].father,ff=t[f].father; int fs=identfy(x),ffs=identfy(f);
int temp=t[x].son[fs^1]; connect(temp,f,fs); connect(f,x,fs^1); connect(x,ff,ffs); pushup(f);pushup(x); } void splay(int at,int to){ to=t[to].father; while(t[at].father!=to){ int up=t[at].father; if(t[up].father==to)rotate(at);
else if(identfy(at)==identfy(up)){ rotate(up); rotate(at); }else{ rotate(at); rotate(at); } } } int create(int val,int father){ tot++; t[tot].val=val; t[tot].father=father; t[tot].size=t[tot].cnt=1; return tot; } void destroy(int x){ t[x].son[0]=t[x].son[1]=t[x].val=t[x].father=t[x].size=t[x].cnt=0; if(x==tot)tot--; } public: int getroot(){return root;} int find(int val){ int now=root; while(1){ if(!now)return 0; if(t[now].val==val){ splay(now,root); return now; } now=t[now].val>val?t[now].son[0]:t[now].son[1]; } } int build(int val){ n++; if(!tot){ root=1; create(val,0); return 0; }else{ int now=root; while(1){ t[now].size++; if(t[now].val==val){ t[now].cnt++; return now; } int nex=t[now].val>val?0:1; if(!t[now].son[nex]){ create(val,now); t[now].son[nex]=tot; return tot; } now=t[now].son[nex]; } } } void push(int val){ int add=build(val); splay(add,root); } void pop(int val){ int pos=find(val); if(!pos)return ; n--; if(t[pos].cnt>1){ t[pos].cnt--; t[pos].size--; return; } if(!t[pos].son[0]){ root=t[pos].son[1]; t[root].father=0; }else if(!t[pos].son[1]){ root=t[pos].son[0]; t[root].father=0; }else{ int pre=t[pos].son[0]; while(t[pre].son[1])pre=t[pre].son[1]; splay(pre,t[pos].son[0]); int temp=t[pos].son[1]; connect(temp,pre,1); connect(pre,0,1);//該樹的超級根是t[0].son[1] pushup(pre); } destroy(pos); } int rank(int val){ int res=0,now=root; while(now){ if(t[now].val==val){ int temp=res+t[t[now].son[0]].size+1; splay(now,root); return temp; } if(t[now].val>val)now=t[now].son[0]; else{ res+=t[t[now].son[0]].size+t[now].cnt; now=t[now].son[1]; } } return 0; } int val(int rank){ if(rank>n)return -INF; int now=root; while(now){ if(t[t[now].son[0]].size>=rank)now=t[now].son[0]; else if(t[t[now].son[0]].size+t[now].cnt>=rank){ splay(now,root); return t[now].val; }else{ rank-=t[t[now].son[0]].size+t[now].cnt; now=t[now].son[1]; } } } int lower(int val){ int now=root,res=-INF; while(now){ if(t[now].val<val&&t[now].val>res)res=t[now].val; if(val>t[now].val)now=t[now].son[1]; else now=t[now].son[0]; } return res; } int upper(int val){ int now=root,res=INF; while(now){ if(t[now].val>val&&t[now].val<res)res=t[now].val; if(val<t[now].val)now=t[now].son[0]; else now=t[now].son[1]; } return res; } void print(int x){//除錯 if(!x)return; print(t[x].son[0]); printf("%d ",t[x].val); print(t[x].son[1]); } #undef root }; Splay T; int m,opt,x; int main(){ T.push(-INF);T.push(INF); scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%d%d",&opt,&x); if(opt==1)T.push(x); if(opt==2)T.pop(x); if(opt==3)printf("%d\n",T.rank(x)-1); if(opt==4)printf("%d\n",T.val(x+1)); if(opt==5)printf("%d\n",T.lower(x)); if(opt==6)printf("%d\n",T.upper(x)); // printf("\ntexting:"); // T.print(T.getroot()); // printf("\n\n"); } return 0; }