题目如同洛谷普通平衡树。
数据加强,
题解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;
}