为什么我的splay旋转破坏了平衡
查看原帖
为什么我的splay旋转破坏了平衡
142549
hbhz_zcy楼主2022/5/30 15:07

由于本人太弱,从spaly开始。
代码主要靠自己参悟,就听了一个思路

//splay
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e5+10,maxh=((1<<30)-1)<<1;
int M,ftop=0,root=1;
struct node{int l,r,v,siz,cnt;}f[maxn];//siz:sumsiz
int qd(){
	int rt=0,k=0;char c=getchar();
	while(c<'0'||c>'9')  k|=(c=='-'),c=getchar();
	while('0'<=c&&c<='9')  rt=(rt<<3)+(rt<<1)+c-48,c=getchar();
	return k?-rt:rt;
}
void dfs(int t){
	printf("ask %d:l=%d r=%d v=%d siz=%d cnt=%d\n",t,f[t].l,f[t].r,f[t].v,f[t].siz,f[t].cnt);
	if(f[t].l){printf("%d->L\n",t);dfs(f[t].l);}
	if(f[t].r){printf("%d->R\n",t);dfs(f[t].r);}
}
void pushup(int t){f[t].siz=f[f[t].l].siz+f[t].cnt+f[f[t].r].siz;}
int ins(int v){f[++ftop]=(node){0,0,v,1,1};return ftop;}
void build(){root=ins(-maxh);ins(maxh);f[1].r=f[1].siz=2;}
void zig(int &t){
	int _l=f[t].l;
	f[t].l=f[_l].r,f[_l].r=t;
	pushup(t);pushup(t=_l);
}
void zag(int &t){
	int _r=f[t].r;
	f[t].r=f[_r].l,f[_r].l=t;
	pushup(t);pushup(t=_r);
}
void change1(int &t,int v){//add
	if(!t){t=ins(v);return;}
	if(v==f[t].v)  f[t].cnt++;
	else if(v<f[t].v)  change1(f[t].l,v);
	else if(v>f[t].v)  change1(f[t].r,v);
	pushup(t);
}
void change2(int &t,int v){//del
	if(!t)  return;
	if(v==f[t].v){
		if(f[t].cnt>1)  f[t].cnt--;
		else if(!f[t].l||!f[t].r)  t=f[t].l+f[t].r;
		else if(f[f[t].l].siz>f[f[t].r].siz)  zig(t),change2(f[t].r,v);
		else zag(t),change2(f[t].l,v);
	}
	else change2(v<f[t].v?f[t].l:f[t].r,v);
	pushup(t);
}
int ask3(int t,int v){//val->rank
	if(!t)  return 0;
	if(v<f[t].v)  return ask3(f[t].l,v);
	if(v>f[t].v)  return f[f[t].l].siz+f[t].cnt+ask3(f[t].r,v);
	return f[f[t].l].siz+1;
}
int ask4(int t,int v){//rank->val
	if(!t)  return 0;
	if(v<=f[f[t].l].siz)  return ask4(f[t].l,v);
	if(v>f[f[t].l].siz+f[t].cnt)  return ask4(f[t].r,v-f[f[t].l].siz-f[t].cnt);
	return f[t].v;
}
int ask5(int t,int v){//_v
	int rt;
	while(t){
		if(f[t].v<v)  rt=f[t].v,t=f[t].r;
		else t=f[t].l;
	}
	return rt;
}
int ask6(int t,int v){//v_
	int rt;
	while(t){
		if(f[t].v>v)  rt=f[t].v,t=f[t].l;
		else t=f[t].r;
	}
	return rt;
}
void splay(int &t,int v){
	if(!t||f[t].v==v)  return;
	if(v<f[t].v)  splay(f[t].l,v),zig(t);
	else if(v>f[t].v)  splay(f[t].r,v),zag(t);
}
int main(){
	M=qd();build();
	while(M--){
		int x=qd(),y=qd(),ans;
		if(x==1)  change1(root,y);
		else if(x==0)  dfs(root);
		else if(x==2)  change2(root,y);
		else if(x==3)  ans=ask3(root,y)-1;
		else if(x==4)  ans=ask4(root,y+1);
		else if(x==5)  ans=ask5(root,y);
		else ans=ask6(root,y);
		if(x>2){splay(root,x==4?ans:y);printf("%d\n",ans);}
	}
	return 0;
}

WA2~10,TLE12
TLE不用管很显然,但是WA很不正常。
请问为什么。

2022/5/30 15:07
加载中...