每次插入都新增一个点可以AC,但如果对于相同的值存在一个点,记录cnt就只有72分,是哪里有问题?
//每次直接插入
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x = 0,f = 1;char ch;
do {ch = getchar();if(ch == '-') f = -1;} while(ch < '0' || ch > '9');
while(ch >= '0' && ch <= '9') x = (x<<1) + (x<<3) + ch-48,ch = getchar();
return x * f;
}
inline void write(int x){
if(x < 0) putchar('-'),x = -x;
if(x > 9) write(x / 10);
putchar(x % 10 + 48);
}
const int N = 100005;
int n,m;
int a[N];
struct Treap{
int tot;
int root,ls[N * 11],rs[N * 11];
struct node{
int val,pri,siz;
}tr[N * 11];
inline void newnode(int val){
tr[++tot] = {val,rand(),1};
}
inline void pushup(int p){
tr[p].siz = tr[ls[p]].siz + tr[rs[p]].siz + 1;
}
inline void split(int p,int rk,int &rt1,int &rt2){
if(!p) {rt1 = rt2 = 0;return ;}
if(tr[ls[p]].siz >= rk) rt2 = p,split(ls[p],rk,rt1,ls[p]);
else rt1 = p,split(rs[p],rk - tr[ls[p]].siz - 1,rs[p],rt2);
pushup(p);
}
inline int merge(int p,int q){
if(!p || !q) return p ^ q;
if(tr[p].pri < tr[q].pri){
rs[p] = merge(rs[p],q),pushup(p);
return p;
}
else {
ls[q] = merge(p,ls[q]),pushup(q);
return q;
}
}
inline int query(int p,int val){
if(!p) return 0;
if(val < tr[p].val) return query(ls[p],val);
else if(val == tr[p].val) return tr[ls[p]].siz;
else return tr[ls[p]].siz + 1 + query(rs[p],val);
}
inline int query_rank(int val){
return query(root,val) + 1;
}
inline void insert(int val){
int rk = query_rank(val);
int rt1;
split(root,rk-1,rt1,root);
newnode(val),root = merge(merge(rt1,tot),root);
}
inline void erase(int val){
int rk = query_rank(val);
int rt1 = 0,rt2;
split(root,rk-1,rt1,root),split(root,1,root,rt2);
root = merge(rt1,rt2);
}
inline int query_val(int rk){
if(rk < 1 || rk > tr[root].siz) return 0;
int rt1 = 0,rt2 = 0,ans;
split(root,rk-1,rt1,root),split(root,1,root,rt2);
ans = tr[root].val;
root = merge(merge(rt1,root),rt2);
return ans;
}
inline int query_pre(int val){
return query_val(query_rank(val) - 1);
}
inline int query_suf(int val){
return query_val(query_rank(val + 1));
}
}T;
signed main(){
n = read(),m = read();
srand(time(0));
for(int i = 1;i <= n;i++) a[i] = read(),T.insert(a[i]);
int lst = 0,ans = 0;
while(m--){
int opt = read(),x = read() ^ lst;
if(opt == 1) T.insert(x);
else if(opt == 2) T.erase(x);
else if(opt == 3) lst = T.query_rank(x),ans ^= lst;
else if(opt == 4) lst = T.query_val(x),ans ^= lst;
else if(opt == 5) lst = T.query_pre(x),ans ^= lst;
else lst = T.query_suf(x),ans ^= lst;
}
write(ans);
return 0;
}
//记录cnt的
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x = 0,f = 1;char ch;
do {ch = getchar();if(ch == '-') f = -1;} while(ch < '0' || ch > '9');
while(ch >= '0' && ch <= '9') x = (x<<1) + (x<<3) + ch-48,ch = getchar();
return x * f;
}
inline void write(int x){
if(x < 0) putchar('-'),x = -x;
if(x > 9) write(x / 10);
putchar(x % 10 + 48);
}
const int N = 100005;
int n,m;
int a[N];
struct Treap{
int tot;
int root,ls[N * 11],rs[N * 11];
struct node{
int val,pri,cnt,siz;
}tr[N * 11];
inline void newnode(int val){
tr[++tot] = {val,rand(),1,1};
}
inline void pushup(int p){
tr[p].siz = tr[ls[p]].siz + tr[rs[p]].siz + tr[p].cnt;
}
inline void split(int p,int rk,int &rt1,int &rt2,int &rt3){
if(!p) {rt1 = rt2 = rt3 = 0;return ;}
if(tr[ls[p]].siz >= rk) rt3 = p,split(ls[p],rk,rt1,rt2,ls[p]);
else if(tr[ls[p]].siz + tr[p].cnt >= rk) rt1 = ls[p],rt2 = p,rt3 = rs[p],ls[p] = rs[p] = 0;
else rt1 = p,split(rs[p],rk-tr[ls[p]].siz-tr[p].cnt,rs[p],rt2,rt3);
pushup(p);
}
inline int merge(int p,int q){
if(!p || !q) return p ^ q;
if(tr[p].pri < tr[q].pri){
rs[p] = merge(rs[p],q),pushup(p);
return p;
}
else {
ls[q] = merge(p,ls[q]),pushup(q);
return q;
}
}
inline int query(int p,int val){
if(!p) return 0;
if(val < tr[p].val) return query(ls[p],val);
else if(val == tr[p].val) return tr[ls[p]].siz;
else return tr[ls[p]].siz + tr[p].cnt + query(rs[p],val);
}
inline int query_rank(int val){
return query(root,val) + 1;
}
inline void insert(int val){
int rk = query_rank(val);
int rt1 = 0,rt2 = 0;
split(root,rk,rt1,root,rt2);
if(tr[root].val == val){
tr[root].cnt++,tr[root].siz++;
root = merge(merge(rt1,root),rt2);
}
else {
newnode(val);
root = merge(merge(merge(rt1,tot),root),rt2);
}
}
inline void erase(int val){
int rk = query_rank(val);
int rt1 = 0,rt2 = 0;
split(root,rk,rt1,root,rt2);
if(tr[root].val != val){
root = merge(merge(rt1,root),rt2);
return ;
}
if(tr[root].cnt > 1){
tr[root].cnt--,tr[root].siz--;
root = merge(merge(rt1,root),rt2);
}
else root = merge(rt1,rt2);
}
inline int query_val(int rk){
if(rk < 1 || rk > tr[root].siz) return 0;
int rt1 = 0,rt2 = 0,ans;
split(root,rk,rt1,root,rt2);
ans = tr[root].val;
root = merge(merge(rt1,root),rt2);
return ans;
}
inline int query_pre(int val){
return query_val(query_rank(val) - 1);
}
inline int query_suf(int val){
return query_val(query_rank(val + 1));
}
}T;
signed main(){
n = read(),m = read();
srand(time(0));
for(int i = 1;i <= n;i++) a[i] = read(),T.insert(a[i]);
int lst = 0,ans = 0;
while(m--){
int opt = read(),x = read() ^ lst;
if(opt == 1) T.insert(x);
else if(opt == 2) T.erase(x);
else if(opt == 3) lst = T.query_rank(x),ans ^= lst;
else if(opt == 4) lst = T.query_val(x),ans ^= lst;
else if(opt == 5) lst = T.query_pre(x),ans ^= lst;
else lst = T.query_suf(x),ans ^= lst;
}
write(ans);
return 0;
}