求助,伸展树板子,操作4查数字有问题
查看原帖
求助,伸展树板子,操作4查数字有问题
131591
蒟蒻君HJT泽渡透香楼主2022/1/25 15:57
#include <bits/stdc++.h>
using namespace std;
int tot=0,fa[100005],ch[100005][2],siz[100005],root=0,cnt[100005],val[100005];
void maintain(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];}
void clear(int x){fa[x]=ch[x][0]=ch[x][1]=siz[x]=cnt[x]=val[x]=0;}
int get(int x){return ch[fa[x]][1]==x;}
void rotate(int x){
	int y=fa[x],chk=get(x),z=fa[y];
	fa[y]=x;fa[x]=z;
	ch[y][chk]=ch[x][chk^1];
	if(ch[x][chk^1])fa[ch[x][chk^1]]=y;
	ch[x][chk^1]=y;
	if(z)ch[z][y==ch[z][1]]=x;
	maintain(x);
	maintain(y);
	return ;
}
void splay(int x){
	if(!x)return ;
	int y=fa[x];
	while(y){
		if(fa[y]){
			if(get(x)==get(y))rotate(y);
			else rotate(x);
		}
		else rotate(x);
		y=fa[x];
	}
	root=x;
	return ;
}
void insert(int x){
	if(!root){
		val[++tot]=x;root=tot;
		siz[root]=1;cnt[root]=1;
		maintain(root);
		return ;
	}
	int now=root,f=0;
	while(true){
		if(val[now]==x){
			++cnt[now];
			maintain(now);
			maintain(f);
			splay(now);
			break;
		}
		f=now;
		now=ch[now][val[now]<x];
		if(!now){
			cnt[++tot]=1;
			val[tot]=x;
			siz[tot]=1;
			fa[tot]=f;
			ch[f][x>val[f]]=tot;
			maintain(tot);
			maintain(f);
			splay(tot);
			break;
		}
	}
	return ;
}
int rk(int x){
	int ans=0,now=root;
	while(1){
		if(val[now]==x){
			int res=ans+siz[ch[now][0]]+1;
			splay(now);
			return res;
		}
		else if(val[now]<x){
			ans+=(siz[ch[now][0]]+cnt[now]);
			now=ch[now][1];
		}
		else now=ch[now][0];
		if(!now)break;
	}
	return 19260817;
}
int getrk(int r){
	int now=root;
	while(1){
		if(r>cnt[now]+siz[ch[now][0]]){
			r-=(cnt[now]+siz[ch[now][0]]);
			now=ch[now][1];
		}
		else if(r<=cnt[now]+siz[ch[now][0]]&&r>siz[ch[now][0]]){
			splay(now);
			return val[now];
		}
		else now=ch[now][0];
	}
	return 19260817;
}
void dele(int x){
	rk(x);
	if(cnt[root]>1){
		--cnt[root];
		maintain(root);
		return ;
	}
	else {
		int r1=ch[root][0],r2=ch[root][1];
		clear(root);
		if(!r1){
			root=r2;
			fa[r2]=0;
			return ;
		}
		if(!r2){
			root=r1;
			fa[r1]=0;
			return ;
		}
		int fd=r1;
		while(true){
			if(ch[fd][1])fd=ch[fd][1];
			else break;
		}
		fa[r1]=0;splay(fd);
		ch[fd][1]=r2;fa[r2]=fd;
		maintain(fd);
	}
	return ;
}
int pre(int x){
	insert(x);
	int now=root;
	now=ch[now][0];
	while(ch[now][1])now=ch[now][1];
	splay(now);
	return val[now];
}
int nxt(int x){
	insert(x);
	int now=root;
	now=ch[now][1];
	while(ch[now][0])now=ch[now][0];
	splay(now);dele(x);
	return val[now];
}
int main(){
	int op,x,n;
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d%d",&op,&x);
		if(op==1){
			insert(x);
		}
		if(op==2)dele(x);
		if(op==3)printf("%d\n",rk(x));
		if(op==4)printf("%d\n",getrk(x));
		if(op==5)printf("%d\n",pre(x)),dele(x);
		if(op==6)printf("%d\n",nxt(x)),dele(x);
	}
	return 0;
}

真的调不出来了,操作4有的时候会死循环,不知道为什么

2022/1/25 15:57
加载中...