【模板】普通平衡树(数据加强版)(洛谷P6136)

【模板】普通平衡树(数据加强版)(洛谷P6136)_第1张图片

#include 

#define endl '\n'
#define int ll
using ll = long long;
typedef unsigned long long ull;
using namespace std;

void GordenGhost();

signed main() {
#ifdef Gorden
    freopen("in.txt", "rt", stdin);
    freopen("out.txt", "wt", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    GordenGhost();
    return 0;
}
const int N =1e6+1e5+7,inf=0x3f3f3f3f3f3f3f3f;
struct node{
    int son[2];//左、右儿
    int fa;
    int v;//点权
    int cnt;//出现次数
    int sz;//子树大小
    void init(int p,int v1){
        fa=p,v=v1;
        cnt=sz=1;
    }
}tr[N];
int root,tot;//节点个数
void pushup(int x){
    tr[x].sz=tr[tr[x].son[0]].sz+tr[tr[x].son[1]].sz+tr[x].cnt;
}
void rotate(int x){ //旋转
    int y=tr[x].fa,z=tr[y].fa,k=tr[y].son[1]==x;//y的右儿是x
    tr[z].son[tr[z].son[1]==y]=x;tr[x].fa=z;//z的儿是x,x的父是z
    tr[y].son[k]=tr[x].son[k^1];tr[tr[x].son[k^1]].fa=y;//y的儿是x的异儿,x的异儿的父是y
    tr[x].son[k^1]=y;tr[y].fa=x;//x的异儿是y,y的父是x
    pushup(y);pushup(x);//自底向上push
}
void splay(int x,int k){ //伸展,x要旋转到k的儿子位置
    while(tr[x].fa!=k) { //折线转xx,直线转yx
        int y=tr[x].fa,z=tr[y].fa;
        if (z!=k) (tr[y].son[0]==x)^(tr[z].son[0]==y)? rotate(x): rotate(y);
        rotate(x);
    }
    if (!k) root=x;//k=0时,x转到根
}
void insert(int v) {
    int x=root,p=0;//x走到空节点或走到目标点结束
    while (x&&tr[x].v!=v) p=x,x=tr[x].son[v>tr[x].v];
    if (x) tr[x].cnt++;//目标点情况
    else {//空节点情况
        x=++tot;
        tr[p].son[v>tr[p].v]=x;
        tr[x].init(p,v);
    }
    splay(x,0);
}
void find(int v){//找到v并转到根
    int x=root;
    while (tr[x].son[v>tr[x].v]&&v!=tr[x].v)
        x=tr[x].son[v>tr[x].v];
    splay(x,0);
}
int getpre(int v){//找前驱
    find(v);
    int x=root;
    if (tr[x].vv) return x;
    x=tr[x].son[1];
    while (tr[x].son[0]) x=tr[x].son[0];
    splay(x,0);
    return x;
}
void del(int v){
    int pre= getpre(v);
    int suc= getsuc(v);
    splay(pre,0);splay(suc,pre);
    int del=tr[suc].son[0];
    if (tr[del].cnt>1) tr[del].cnt--, splay(del,0);
    else tr[suc].son[0]=0, splay(suc,0);
}
int getrank(int v){//查找v的排名
    insert(v);
    int res=tr[tr[root].son[0]].sz;
    del(v);
    return res;
}
int getval(int k) {//查找排名为k的数值
    k++;
    int x=root;
    while (1) {
        if (k<=tr[tr[x].son[0]].sz) x=tr[x].son[0];
        else if (k<=tr[tr[x].son[0]].sz+tr[x].cnt) break;
        else k-=tr[tr[x].son[0]].sz+tr[x].cnt,x=tr[x].son[1];
    }
    splay(x,0);
    return tr[x].v;
}
void GordenGhost() {
    insert(-inf);insert(inf);
    int n,m,op,x,ans=0,la=0;
    cin>>n>>m;
    for (int i=1;i<=n;++i) {
        int a;
        cin>>a;
        insert(a);
    }
    while (m--) {
        cin>>op>>x;
        x^=la;
        if (op==1) insert(x);
        else if (op==2) del(x);
        else if (op==3) la=getrank(x),ans^=la;
        else if (op==4) la=getval(x),ans^=la;
        else if (op==5) la=tr[getpre(x)].v,ans^=la;
        else if (op==6) la=tr[getsuc(x)].v,ans^=la;
//        cout<

你可能感兴趣的:(算法,c++,洛谷,平衡树,数据结构,splay)