指针splay
怀疑操作2,5,6有问题
有时候越界
求调
#include<bits/stdc++.h>
using namespace std;
const int N=100005,inf=1e9;
inline int rd()
{
int x=0,y=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')y=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
return x*y;
}
int n,size;
struct node *null;//空
struct node
{
node *ch[2],*fa;//儿子,父亲
int w,sz,flag,cnt;//值(可以加id),体积,翻转懒标记 ,相同值个数
#define ND node*
node(int x)
{
ch[0]=ch[1]=fa=null;
w=x;
sz=1;
flag=0;
cnt=1;
}//新建
void pp()
{
sz=cnt+ch[0]->sz+ch[1]->sz;
return;
}
void pd()
{
if(flag)
{
swap(ch[0],ch[1]);
ch[0]->flag^=1;
ch[1]->flag^=1;
flag=0;
}
return;
}
}*root;
void init()
{
null=new node(-inf);
null->sz=null->cnt=0;
root=null;
}
/*
初始化
Tips:
一定要把null的sz赋值为0
不然在pushup时会多加空
*/
void rotate(ND x)
{
ND y=x->fa;
ND z=y->fa;
int k=y->ch[1]==x;
z->ch[z->ch[1]==y]=x;
x->fa=z;
y->ch[k]=x->ch[k^1];
x->ch[k^1]->fa=y;
x->ch[k^1]=y;
y->fa=x;
y->pp();
x->pp();
return;
}
//旋转
void splay(ND x,ND k)
{
while(x->fa!=k)
{
ND y=x->fa;
ND z=y->fa;
if(z!=k)
{
if((y->ch[1]==x)^(z->ch[1]==y))rotate(x);
else rotate(y);
}
rotate(x);
}
if(k==null)root=x;
return;
}
//伸展
void insert(int v)
{
ND u=root;
ND p=null;
while(u!=null)
{
if(v==u->w)
{
++u->cnt;
return;
}
p=u;
u=u->ch[v>u->w];
}
u=new node(v);
if(p!=null)p->ch[v>p->w]=u;
u->fa=p;
splay(u,null);
++size;
return;
}
//插入
ND findkth(int k)
{
if(k>size)return null;
ND u=root;
while(true)
{
u->pd();
if(u->ch[0]->sz>=k)u=u->ch[0];
else if(u->ch[0]->sz+1==k)return u;
else
{
k-=u->ch[0]->sz+1;
u=u->ch[1];
}
}
return null;
}
//找第k大
pair<ND,int>findk(int w)
{
ND u=root;
int num=0,mx=root->w;
while(u!=null)
{
u->pd();
if(w<u->w)
{
mx=u->w;
u=u->ch[0];
}
else
{
num+=u->ch[0]->sz;
if(u->w<=mx)return make_pair(u,num+u->ch[0]->sz);
u=u->ch[1];
}
}
return make_pair(u->fa,num-1);
}
//找k第几大
ND pre(int w)
{
ND u=findk(w).first;
splay(u,null);
if(u->w==w)
{
u=u->ch[0];
while(u->ch[1]!=null)u=u->ch[1];
}
return u;
}
//前驱
ND nex(int w)
{
ND u=findk(w).first->fa;
splay(u,null);
if(u->w==w)
{
u=u->ch[1];
while(u->ch[0]!=null)u=u->ch[0];
}
return u;
}
//后继
void kill(int w)
{
ND l=pre(w);
ND r=nex(w);
splay(l,null);
splay(r,l);
ND u=r->ch[0];
--size;
if(--u->cnt==0)
{
r->ch[0]=null;
r->pp();
u=null;
}
return;
}
//删除
void output(ND f)
{
f->pd();
if(f->ch[0]!=null)output(f->ch[0]);
if(f->w!=-inf&&f->w!=inf)printf("%d %d %d %d %d\n",f->w,f->sz,f->fa->w,f->ch[0]->w,f->ch[1]->w);
if(f->ch[1]!=null)output(f->ch[1]);
return;
}
//中序输出
int main()
{
init();
n=rd();
insert(inf);
--size;root->cnt=root->sz=0;
while(n--)
{
int opt=rd(),w=rd();
if(opt==1)insert(w);
if(opt==2)kill(w); //bug
if(opt==3)printf("%d\n",findk(w).second);
if(opt==4)printf("%d\n",findkth(w)->w);
if(opt==5)printf("%d\n",pre(w)->w); //bug
if(opt==6)printf("%d\n",nex(w)->w); //bug
output(root);
putchar('\n');
}
return 0;
}
/*
21
1 1
1 10
1 100
1 1000
1 10000
3 10
3 100
4 2
4 4
5 20
5 200
6 20
6 200
2 10
*/