题目如同洛谷普通平衡树。
数据加强,
题解rank1是 WBLT 写的,本来想学一下,但是我这个 SBT 跑的还是蛮快的,就不学了。
目前洛谷rank3,可是rank1,rank2都是SBT 写的。。为啥比我的要快。。

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#define ll long long
#define llu unsigned ll
using namespace std;


char buffer[100001], * S, * T;
inline char Get_Char()
{
    if (S == T)
    {
        T = (S = buffer) + fread(buffer, 1, 100001, stdin);
        if (S == T) return EOF;
    }
    return *S++;
}
inline int read()
{
    char c;int re = 0;
    for (c = Get_Char();c < '0' || c>'9';c = Get_Char());
    while (c >= '0' && c <= '9') re = re * 10 + (c - '0'), c = Get_Char();
    return re;
}


const double alpha = 0.75;
const int maxn = 1100100;
const int inf = 0x7fffffff;
struct node
{
    int val;
    int lc, rc;
    int si;
}t[maxn];
int tot, root;


void pushup(int p)
{
    t[p].si = t[t[p].lc].si + t[t[p].rc].si + 1;
}


int newnode(int x)
{
    int p = ++tot;
    t[p].lc = t[p].rc = 0;
    t[p].si = 1;
    t[p].val = x;
    return p;
}

void R(int& p)
{
    int q = t[p].lc;
    t[p].lc = t[q].rc;
    t[q].rc = p;
    p = q;
    pushup(t[p].rc);
    pushup(p);

}

void L(int& p)
{
    int q = t[p].rc;
    t[p].rc = t[q].lc;
    t[q].lc = p;
    p = q;
    pushup(t[p].lc);
    pushup(p);
}

void RL(int& p)
{
    R(t[p].rc);
    L(p);
}

void LR(int& p)
{
    L(t[p].lc);
    R(p);
}


int getmin(int p)
{
    while (t[p].lc) p = t[p].lc;
    return p;
}

int getmax(int p)
{
    while (t[p].rc) p = t[p].rc;
    return p;
}

void maintain(int& p, bool flag)
{
    if (!flag)
    {
        if (t[t[t[p].lc].lc].si > t[t[p].rc].si)
            R(p);
        else if (t[t[t[p].lc].rc].si > t[t[p].rc].si)
            LR(p);
        else return;
    }
    else
    {
        if (t[t[t[p].rc].rc].si > t[t[p].lc].si)
            L(p);
        else if (t[t[t[p].rc].lc].si > t[t[p].lc].si)
            RL(p);
        else return;
    }
    maintain(t[p].lc, false);
    maintain(t[p].rc, true);
    maintain(p, true);
    maintain(p, false);
}

void _insert(int& now, int val)
{
    if (!now)
    {
        now = newnode(val);
        return;
    }
    if (val < t[now].val)
    {
        _insert(t[now].lc, val);
        maintain(now, false);
    }
    else
    {
        _insert(t[now].rc, val);
        maintain(now, true);
    }
    pushup(now);
}

void del(int& p, int x)
{
    if (x < t[p].val)
        del(t[p].lc, x);
    else if (x > t[p].val)
        del(t[p].rc, x);
    else
    {
        if (t[p].lc && t[p].rc)
        {
            int q = getmax(t[p].lc);
            t[p].val = t[q].val;
            del(t[p].lc, t[q].val);
        }
        else
        {
            if (t[p].lc) p = t[p].lc;
            else p = t[p].rc;
            return;
        }
    }
    pushup(p);
}


int get_rank(int x)
{
    int now = root, ans = 0;
    while (now)
    {
        if (t[now].val < x) ans += t[t[now].lc].si + 1, now = t[now].rc;
        else now = t[now].lc;
    }
    return ans + 1;
}

int get_val(int k)
{
    int now = root;
    while (1)
    {
        if (t[t[now].lc].si + 1 == k) return t[now].val;
        else if (t[t[now].lc].si >= k) now = t[now].lc;
        else k -= t[t[now].lc].si + 1, now = t[now].rc;
    }
}

int get_front(int x)
{
    int now = root, ans = -inf;
    while (now)
    {
        if (t[now].val < x) ans = max(ans, t[now].val), now = t[now].rc;
        else now = t[now].lc;
    }
    return ans;
}

int get_behind(int x)
{
    int now = root, ans = inf;
    while (now)
    {
        if (t[now].val > x) ans = min(ans, t[now].val), now = t[now].lc;
        else now = t[now].rc;
    }
    return ans;
}

int main(void)
{
    int n,m,val;
    n = read(), m = read();
    for (int i = 1;i <= n;i++)
        val=read(), _insert(root, val);

    int pos, x;
    int ans = 0,last=0;
    for (int i = 1;i <= m;i++)
    {
        pos = read(), x = read();
        x ^= last;
        if (pos == 1)
            _insert(root, x);
        else if (pos == 2)
            del(root, x);
        else if (pos == 3)
            ans^=(last=get_rank(x));
        else if (pos == 4)
            ans^=(last=get_val(x));
        else if (pos == 5)
            ans^=(last=get_front(x));
        else if (pos == 6)
            ans^=(last=get_behind(x));
    }
    printf("%d\n", ans);
    return 0;
}