准备去搞一搞 LCT,听说需要 Splay 前置知识,先回来打了一发 Splay 复习一下。
结果似乎 RE 了的样子。。
输出全部正确,不过最后会 RE 一下qwq......
其实很久以前我打的 Splay 也出现过这个问题
然后东改改西改改玄学正确了就没管它
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cctype>
#define MAXN 100005
#define int long long
using namespace std;
struct Node{
int ch[2],val,size,num,father;
Node(int l,int r,int v,int s,int n,int f){
ch[0]=l,ch[1]=r,val=v,size=s,num=n,father=f;
}
Node(){}
};
int rt,cnt;
struct Splay{
Node t[MAXN];
inline void pushup(int o){
t[o].size=t[t[o].ch[0]].size+t[t[o].ch[1]].size+t[o].num;
}
inline void clear(int o){
t[o]=Node(0,0,0,0,0,0);
}
inline bool get(int o){
return o==t[t[o].father].ch[1];
}
inline void rotate(int o){
int x=t[o].father,y=t[x].father;
int r=get(o);
t[x].ch[r]=t[o].ch[r^1];
t[t[o].ch[r^1]].father=x;
t[o].ch[r^1]=x;
t[x].father=o;
t[o].father=y;
if(y)t[y].ch[x==t[y].ch[1]]=o;
pushup(o);
pushup(x);
}
inline void splay(int o){
for(int f=t[o].father;f=t[o].father,f;rotate(o)){
if(t[f].father)rotate(get(o)==get(f)?f:o);
}
rt=o;
}
inline void insert(int x){
if(!rt){
t[rt=++cnt].val=x;
t[cnt].num++;
pushup(rt);
return ;
}
int cur=rt,f=0;
while(1){
if(t[cur].val==x){
t[cur].num++;
pushup(cur);
pushup(f);
splay(cur);
break;
}
f=cur;
cur=t[cur].ch[t[cur].val<x];
if(!cur){
t[rt=++cnt].val=x;
t[cnt].num++;
t[cnt].father=f;
t[f].ch[t[f].val<x]=cnt;
pushup(cnt);
pushup(f);
splay(cnt);
break;
}
}
}
inline int rnk(int x){
int ans=0,cur=rt;
while(1){
if(x<t[cur].val){
cur=t[cur].ch[0];
}
else{
ans+=t[t[cur].ch[0]].size;
if(x==t[cur].val){
splay(cur);
return ans+1;
}
ans+=t[cur].num;
cur=t[cur].ch[1];
}
}
}
inline int kth(int x){
int cur=rt;
while(1){
if(t[cur].ch[0]&&x<=t[t[cur].ch[0]].size){
cur=t[cur].ch[0];
}
else{
x-=t[t[cur].ch[0]].size+t[cur].num;
if(x<=0){
splay(cur);
return t[cur].val;
}
cur=t[cur].ch[1];
}
}
}
inline int pre(){
int cur=t[rt].ch[0];
while(t[cur].ch[1])cur=t[cur].ch[1];
splay(cur);
return cur;
}
inline int nxt(){
int cur=t[rt].ch[1];
while(t[cur].ch[0])cur=t[cur].ch[0];
splay(cur);
return cur;
}
inline void del(int x){
rnk(x);
if(t[rt].num>1){
t[rt].num--;
pushup(rt);
return ;
}
if(!t[rt].ch[0]&&!t[rt].ch[1]){
clear(rt);
rt=0;
return ;
}
if(!t[rt].ch[0]){
int cur=rt;
rt=t[rt].ch[1];
t[rt].father=0;
clear(cur);
return ;
}
if(!t[rt].ch[1]){
int cur=rt;
rt=t[rt].ch[0];
t[rt].father=0;
clear(cur);
}
int cur=rt;
int k=pre();
splay(x);
t[t[cur].ch[1]].father=k;
t[k].ch[1]=t[cur].ch[1];
clear(cur);
pushup(rt);
}
};
Splay tree;
signed main(void){
int n,opt,x;
scanf("%lld",&n);
while(n--){
scanf("%lld%lld",&opt,&x);
if(opt==1){
tree.insert(x);
}
else if(opt==2){
tree.del(x);
}
else if(opt==3){
printf("%lld\n",tree.rnk(x));
}
else if(opt==4){
printf("%lld\n",tree.kth(x));
}
else if(opt==5){
tree.insert(x);
printf("%lld\n",tree.t[tree.pre()].val);
tree.del(x);
}
else if(opt==6){
tree.insert(x);
printf("%lld\n",tree.t[tree.nxt()].val);
tree.del(x);
}
}
return 0;
}
对于很多数据,程序输出完正确输出数据之后终端都会显示一个 zsh: segmentation fault
/kk
求大佬帮忙看看/kel