呜呜呜怎么卡过去啊……

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

Warriors_Cat @ 2020-02-28 21:39:19

### $Code:
#pragma GCC optimize(3)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
using namespace std;
const int INF = 0x7fffffff;
int anss, lst, m, n, opt, x, num, Root, ch[1100010][2], cnt[1100010], siz[1100010], pri[1100010], val[1100010];
inline int new_node(int x){
    val[++num] = x;
    pri[num] = rand();
    cnt[num] = siz[num] = 1;
    return num;
}
inline int read(){
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x << 3) + (x << 1) + (ch ^ 48);
        ch = getchar();
    }
    return x * f;
}
inline void upd(int x){
    siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + cnt[x];
    return;
}
inline void Rotate(int &x, int id){
    int y = ch[x][id ^ 1];
    ch[x][id ^ 1] = ch[y][id];
    ch[y][id] = x;
    x = y;
    upd(ch[x][id]); upd(x);
    return;
}
inline void Insert(int &x, int key){
    if(!x){
        x = new_node(key);
        return;
    }
    if(key == val[x]) cnt[x]++;
    else{
        int id = key < val[x] ? 0 : 1;
        Insert(ch[x][id], key);
        if(pri[x] < pri[ch[x][id]]) Rotate(x, id ^ 1);
    }
    upd(x);
    return;
}
inline void Delete(int &x, int key){
    if(!x) return;
    if(key == val[x]){
        if(cnt[x] > 1){
            cnt[x]--;
            upd(x);
            return;
        }
        if(ch[x][0] || ch[x][1]){
            if(!ch[x][1] && pri[ch[x][0]] > pri[ch[x][1]]){
                Rotate(x, 1);
                Delete(ch[x][1], key);
            }
            else{
                Rotate(x, 0);
                Delete(ch[x][0], key);
            }
            upd(x);
        }
        else x = 0;
        return;
    }
    if(key < val[x]) Delete(ch[x][0], key);
    else Delete(ch[x][1], key);
    upd(x);
    return;
}
inline int Pre(int key){
    int x = Root, ans = -INF;
    while(x){
        if(val[x] < key) ans = val[x], x = ch[x][1];
        else x = ch[x][0];
    }
    return ans;
}
inline int Suf(int key){
    int x = Root, ans = INF;
    while(x){
        if(val[x] > key) ans = val[x], x = ch[x][0];
        else x = ch[x][1];
    }
    return ans;
}
inline int Find(int x, int key){
    if(!x) return 0;
    if(key == val[x]) return siz[ch[x][0]] + 1;
    else if(key < val[x]) return Find(ch[x][0], key);
    else return siz[ch[x][0]] + cnt[x] + Find(ch[x][1], key);
}
inline int Rank(int x, int k){
    if(!x) return INF;
    if(k <= siz[ch[x][0]]) return Rank(ch[x][0], k);
    else if(k <= siz[ch[x][0]] + cnt[x]) return val[x];
    else return Rank(ch[x][1], k - siz[ch[x][0]] - cnt[x]);
}
int main(){
    Root = new_node(-INF), ch[Root][1] = new_node(INF);
    upd(Root);
    n = read(); m = read();
    for(register int i = 1; i <= n; ++i){
        x = read();
        Insert(Root, x);
    }
    for(register int i = 1; i <= m; ++i){
        opt = read(); x = read();
        x ^= lst;
        if(opt == 1) Insert(Root, x);
        if(opt == 2) Delete(Root, x);
        if(opt == 3) Insert(Root, x), lst = Find(Root, x) - 1, anss ^= lst, Delete(Root, x);
        if(opt == 4) lst = Rank(Root, x + 1), anss ^= lst;
        if(opt == 5) Insert(Root, x), lst = Pre(x), anss ^= lst, Delete(Root, x);
        if(opt == 6) Insert(Root, x), lst = Suf(x), anss ^= lst, Delete(Root, x);
    }
    printf("%d", anss);
    return 0;
}

by zl_just @ 2020-02-28 21:41:44

卡常就用指针呀(雾 qwq


by zl_just @ 2020-02-28 21:44:04

treap有O(n)建树,比较有效


|