WCPWCPWCP @ 2022-08-25 19:06:45
#include<iostream>
#include<climits>
#define maxn 2000010
using namespace std;
struct node{
int s[2],p,cnt,v,siz;
void init(int p1,int v1){
p=p1,v=v1;
cnt=siz=1;
}
}tr[maxn];
int root,idex,ans=0,last=0;
int read(){
int res=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-'){
f=f*-1;
}
c=getchar();
}
while(c>='0'&&c<='9'){
res=res*10+c-'0';
c=getchar();
}
return res*f;
}
void write(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
void pushup(int node){
tr[node].siz=tr[tr[node].s[0]].siz+tr[tr[node].s[1]].siz+tr[node].cnt;
}
void rotate(int x){
int y=tr[x].p,z=tr[y].p;
int k=tr[y].s[1]==x;
tr[y].s[k]=tr[x].s[k^1];
tr[tr[x].s[k^1]].p=y;
tr[x].s[k^1]=y;
tr[y].p=x;
tr[x].p=z;
tr[z].s[tr[z].s[1]==y]=x;
pushup(y);
pushup(x);
}
void splay(int x,int u){
while(tr[x].p!=u){
int y=tr[x].p,z=tr[y].p;
if(z!=u){
if((tr[z].s[0]==y)^(tr[y].s[0]==x)){
rotate(x);
}
else{
rotate(y);
}
}
else{
rotate(x);
}
}
if(u==0) root=x;
}
void find(int v){
int x=root;
while(tr[x].s[v>tr[x].v]&&v!=tr[x].v){ // ???
x=tr[x].s[v>tr[x].v];
}
splay(x,0);
}
int find_xrk(int x){ // 需要保证查找的数在树里面 ,也可以先加入一个数再删除掉
find(x);
return tr[tr[root].s[0]].siz;
}
inline int getrank(int x){ // 不需要保证数在树里面
int cur=root,ret=0;
while(cur){
if(tr[cur].v==x){
ret+=tr[tr[cur].s[0]].siz;
splay(cur,0); return ret;
}
if(tr[cur].v>x)
cur=tr[cur].s[0];
else
ret+=tr[tr[cur].s[0]].siz+tr[cur].cnt,cur=tr[cur].s[1];
}
if(tr[cur].v==x){
splay(cur,0);
}
else{
splay(tr[cur].p,0);
}
return ret;
}
int find_rkx(int k){
int x=root;
while(1){
if(tr[x].cnt+tr[tr[x].s[0]].siz<k){
k-=tr[x].cnt+tr[tr[x].s[0]].siz;
x=tr[x].s[1];
}
else{
if(tr[tr[x].s[0]].siz>=k){
x=tr[x].s[0];
}
else{
break;
}
}
}
splay(x,0);
return tr[x].v;
}
int find_pre(int v){
find(v);
int x=root;
if(tr[x].v<v){
return x;
}
x=tr[x].s[0];
while(tr[x].s[1]){
x=tr[x].s[1];
}
//splay(x,0);
return x;
}
int find_rea(int v){
find(v);
int x=root;
if(tr[x].v>v){
return x;
}
x=tr[x].s[1];
while(tr[x].s[0]){
x=tr[x].s[0];
}
//splay(x,0);
return x;
}
void ldelete(int x){
int pre=find_pre(x);
int rea=find_rea(x);
splay(pre,0);
splay(rea,pre);
if(tr[tr[rea].s[0]].cnt>1){
tr[tr[rea].s[0]].cnt--;
splay(tr[rea].s[0],0);
}
else{
tr[rea].s[0]=0;
splay(rea,0);
}
}
void insert(int v){
int x=root,p=0;
while(x&&tr[x].v!=v){
p=x;x=tr[x].s[v>tr[x].v];
}
if(x) tr[x].cnt++;
else{
x=++idex;
tr[p].s[v>tr[p].v]=x;
tr[x].init(p,v);
}
splay(x,0);
}
int main()
{
int n,m;
n=read(),m=read();
insert(-INT_MAX);
insert(INT_MAX);
for(int i=1;i<=n;i++){
int a;
a=read();
insert(a);
}
for(int i=1;i<=m;i++){
int op,x;
op=read(),x=read();
x=(x^last);
if(op==1){
insert(x);
}
else if(op==2){
ldelete(x);
}
else if(op==3){
int tmp=getrank(x);
ans^=tmp;
last=tmp;
}
else if(op==4){
int tmp=find_rkx(x+1);
ans^=tmp;
last=tmp;
}
else if(op==5){
int tmp=tr[find_pre(x)].v;
ans^=tmp;
last=tmp;
}
else if(op==6){
int tmp=tr[find_rea(x)].v;
ans^=tmp;
last=tmp;
}
}
write(ans);
return 0;
}
by WCPWCPWCP @ 2022-08-25 21:27:12
第10个点一直是tle的,qaq
by WCPWCPWCP @ 2022-08-26 10:14:26
第10个点只有插入和删除操作,插入的时候正常,删除的时候跑很慢
by WCPWCPWCP @ 2022-08-26 11:06:51
此贴终
if((tr[z].s[0]==y)^(tr[y].s[0]==x)){
rotate(x);
}
else{
rotate(y);
}
不应该要else的,警示后人qaq