Pursuer017 @ 2021-01-05 16:26:12
请问这题会卡双旋Splay吗。我一直被卡T,只有30pts,不知道是我写挂了,还是正常Splay就过不了?
谢谢
挂一下我Splay代码,有兴趣的大佬可以帮忙看看嘛QAQ
(弱化版数据可以通过)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#define rint register int
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template<class T>inline void read(T &x){
x=0;char c=getchar();int f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=f;
}
const int N=1100010;
const int INF=0x7fffffff;
int n,m;
struct node{
int s[2],p;
int v,size,cnt;
void init(int _v,int _p){
v=_v;p=_p;
size=cnt=1;
}
}tr[N];
int root,idx;
void Pushup(int x){
tr[x].size=tr[tr[x].s[0]].size
+tr[tr[x].s[1]].size+tr[x].cnt;
}
void Rotate(int x){
int y=tr[x].p,z=tr[y].p;
int k=tr[y].s[1]==x;
tr[z].s[tr[z].s[1]==y]=x,tr[x].p=z;
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;
Pushup(y);Pushup(x);
}
void Splay(int x,int k){
while(tr[x].p!=k){
int y=tr[x].p,z=tr[y].p;
if(z!=k){
if((tr[z].s[1]==y)^(tr[y].s[1]==x)) Rotate(x);
else Rotate(y);
}
Rotate(x);
}
if(!k) root=x;
}
void Insert(int x){
int u=root,p=0;
while(u&&tr[u].v!=x)
p=u,u=tr[u].s[x>tr[u].v];
if(u) tr[u].cnt++;
else{
u=++idx;
if(p) tr[p].s[x>tr[p].v]=u;
tr[u].init(x,p);
}
Splay(u,0);
}
void Find(int x){
int u=root;
while(tr[u].s[x>tr[u].v]&&tr[u].v!=x)
u=tr[u].s[x>tr[u].v];
Splay(u,0);
}
int Next(int x,int f){
Find(x);
int u=root;
if((x<tr[u].v&&f)||(x>tr[u].v&&!f)) return u;
u=tr[u].s[f];
while(tr[u].s[f^1]) u=tr[u].s[f^1];
return u;
}
void Delete(int x){
int pre=Next(x,0);
int nxt=Next(x,1);
Splay(pre,0);Splay(nxt,pre);
int del=tr[nxt].s[0];
if(tr[del].cnt>1){
tr[del].cnt--;
Splay(del,0);
}
else tr[nxt].s[0]=0;
}
int K_th(int x){
int u=root;
if(tr[u].size<=x) x=tr[u].size-1;
while(1){
int y=tr[u].s[0];
if(x<=tr[y].size) u=y;
else if(x>tr[y].size+tr[u].cnt) {
x-=tr[y].size+tr[u].cnt;
u=tr[u].s[1];
}
else return tr[u].v;
}
}
int main(){
read(n);
read(m);
Insert(INF);
Insert(-INF);
for(rint i=1;i<=n;i++) {
int x;read(x);
Insert(x);
}
int last=0,ans=0;
while(m--){
int opt,x;
read(opt);read(x);x^=last;
if(opt==1) Insert(x);
if(opt==2) Delete(x);
if(opt>=3){
if(opt==3){
Find(x);
last=tr[tr[root].s[0]].size;
}
if(opt==4) last=K_th(x+1);
if(opt==5) last=tr[Next(x,0)].v;
if(opt==6) last=tr[Next(x,1)].v;
ans^=last;
}
}
printf("%d\n",ans);
return 0;
}
by suyue1098765432 @ 2021-01-05 17:04:44
@lrz 求前驱后继和第k大数之后要把他splay到根节点
by cunzai_zsy0531 @ 2021-01-05 18:14:41
@lrz 不会卡,我过了
by Pursuer017 @ 2021-01-05 19:13:47
@cunzai_zsy0531 谢谢Thanks♪(・ω・)ノ
by Pursuer017 @ 2021-01-05 19:15:14
@suyue1098765432 谢谢Thanks♪(・ω・)ノ
加上后略快一些,但还是T,我可能是部分写法有问题
by Pursuer017 @ 2021-01-07 18:28:23
破案了QWQ
查询排名的时候没考虑到找不到x的情况233