TreapLE 40

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

Okimoto @ 2020-12-18 19:05:29

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
struct node{
    int vl;
    int lc;
    int rc;
    int pr;
    int sz;
    int cn;
};
inline int get(){
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9'){
        if(ch=='-'){
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
int n, m, p, rt;
int last, ans;
node t[1100007];
inline void upd(int k){
    t[k].sz = t[k].cn + t[t[k].lc].sz + t[t[k].rc].sz;
}
inline void zig(int & k){
    int y = t[k].lc;
    t[k].lc = t[y].rc;
    t[y].rc = k;
    t[y].sz = t[k].sz;
    upd(k);
    k = y;
}
inline void zag(int & k){
    int y = t[k].rc;
    t[k].rc = t[y].lc;
    t[y].lc = k;
    t[y].sz = t[k].sz;
    upd(k);
    k = y;
}
inline void ins(int & k, const int &v){
    if(k == 0){
        k = ++ p;
        t[k].lc = 0;
        t[k].rc = 0;
        t[k].vl = v;
        t[k].sz = 1;
        t[k].cn = 1;
        t[k].pr = rand();
        return;
    }
    t[k].sz ++;
    if(v == t[k].vl){
        t[k].cn ++;
    }
    else if(v < t[k].vl){
        ins(t[k].lc, v);
        upd(k);
        if(t[t[k].lc].pr < t[k].pr){
            zig(k);
        }
    }
    else{
        ins(t[k].rc, v);
        upd(k);
        if(t[t[k].rc].pr < t[k].pr){
            zag(k);
        }
    }
}
inline void del(int & k, const int &v){
    if(v == t[k].vl){
        if(t[k].cn > 1){
            t[k].cn --;
            t[k].sz --;
            return;
        }
        else if(t[k].lc == 0 || t[k].rc == 0){
            k = t[k].lc + t[k].rc;
        }
        else if(t[t[k].lc].pr < t[t[k].rc].pr){
            zig(k);
            del(k, v);
            upd(k);
        }
        else{
            zag(k);
            del(k, v);
            upd(k);
        }
        return;
    }
    t[k].sz --;
    if(v < t[k].vl){
        del(t[k].lc, v);
        upd(k);
    }
    else{
        del(t[k].rc, v);
        upd(k);
    }
}
inline int rnk(int k, const int &v){
    if(k == 0){
        return 1;
    }
    if(v == t[k].vl){
        return 1;
    }
    else if(v < t[k].vl){
        return rnk(t[k].lc, v);
    }
    else{
        return t[t[k].lc].sz + t[k].cn + rnk(t[k].rc, v);
    }
}
inline int ith(int k, const int &i){
    if(i <= t[t[k].lc].sz){
        return ith(t[k].lc, i);
    }
    else if(i <= t[t[k].lc].sz + t[k].cn){
        return t[k].vl;
    }
    else{
        return ith(t[k].rc, i - t[t[k].lc].sz - t[k].cn);
    }
}
inline int pre(const int &v){
    int r = 0;
    int k = rt;
    while(k){
        if(v > t[k].vl){
            r = t[k].vl;
            k = t[k].rc;
        }
        else{
            k = t[k].lc;
        }
    }
    return r;
}
inline int suf(const int &v){
    int r = 0;
    int k = rt;
    while(k){
        if(v < t[k].vl){
            r = t[k].vl;
            k = t[k].lc;
        }
        else{
            k = t[k].rc;
        }
    }
    return r;
}
int main(){
    srand(time(0));
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i ++){
        int a;
        a = get();
        ins(rt, a);
    }
    for(int i = 0; i < m; i ++){
        int opt;
        int x_;
        scanf("%d%d", &opt, &x_);
        int x = x_ ^ last;
        if(opt == 1){
            ins(rt, x);
        }
        else if(opt == 2){
            del(rt, x);
        }
        else if(opt == 3){
            last = rnk(rt, x);
            ans ^= last;
        }
        else if(opt == 4){
            last = ith(rt, x);
            ans ^= last;
        }
        else if(opt == 5){
            last = pre(x);
            ans ^= last;
        }
        else{
            last = suf(x);
            ans ^= last;
        }
    }
    printf("%d", ans);
    return 0;
}

|