求助
查看原帖
求助
143925
吴勉之楼主2021/9/25 12:27

指针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
*/
2021/9/25 12:27
加载中...