Warriors_Cat @ 2020-02-28 21:39:19
#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)建树,比较有效