求助 splay 复杂度
查看原帖
求助 splay 复杂度
128870
chen_qian楼主2021/3/25 18:37
#include<bits/stdc++.h>
#define N 2000005
#define INF 2000001
using namespace std;
int n,pos;
char s[N];
int root,tot,val[N],ch[N][2],size[N],fa[N];
int a[N];
//操作支持:
//找rank 
//插入,直接建成平衡树 
//删除,断开,垃圾回收 
//输出 
int newnode(){
	return ++tot;
}
void clear(int x){
	ch[x][0]=ch[x][1]=fa[x]=size[x]=val[x]=0;
}
bool get(int x){
	return x==ch[fa[x]][1];
}
void push_up(int x){
	size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void rotate(int x){
	int y=fa[x],z=fa[y],chk=get(x);
	if(z) ch[z][ch[z][1]==y]=x;
	ch[y][chk]=ch[x][chk^1];
	fa[ch[x][chk^1]]=y;
	ch[x][chk^1]=y;
	fa[y]=x;
	fa[x]=z;
	push_up(y);
	push_up(x);
}
void splay(int x,int goal){
	for(int f;f=fa[x],f!=goal;rotate(x)){
		if(fa[f]) rotate(get(f)==get(x)?f:x);
	}
	if(!goal) root=x;
}
int build(int f,int l,int r){
	if(l>r) return 0;
	int mid=(l+r)>>1;
	int x=newnode();
	fa[x]=f;
	val[x]=a[mid];
	ch[x][0]=build(x,l,mid-1);
	ch[x][1]=build(x,mid+1,r);
	push_up(x);
	return x;
}
int queryrank(int k){
	int x=root;
	while(1){
		//cout<<ch[x][0]<<' '<<size[]<<endl; 
		if(k<=size[ch[x][0]]&&ch[x][0]) x=ch[x][0];
		else{
			k-=size[ch[x][0]]+1;
			if(k<=0){
				splay(x,0);
				return x;
			}
			x=ch[x][1];
		}
	}
}
void insert(int len){
	for(int i=1;i<=len;++i) {
        s[i]=getchar();
        if(s[i]=='\n'||s[i]=='\r') --i;
    }
    for(int i=1;i<=len;i++) a[i]=s[i]-32;
	int x=queryrank(pos),y=queryrank(pos+1),p=build(0,1,len);
	splay(x,0);
	splay(y,x);	
	ch[y][0]=p;
	fa[p]=y;
	push_up(y);
	push_up(x);
}
void del(int len){
	int x=queryrank(pos),y=queryrank(pos+len+1);
	splay(x,0);
	splay(y,x);
	int p=ch[y][0];
	ch[y][0]=0;
	push_up(y);
	push_up(x);
}
void print(int x){
	if(ch[x][0]) print(ch[x][0]);
	if(x!=1&&x!=2){
		char c=val[x]+32;
		putchar(c);
	}
	if(ch[x][1]) print(ch[x][1]);	
}
int main(){
	scanf("%d",&n);
	pos=1;
	a[1]=0,a[2]=INF;
	root=build(0,1,2);
	while(n--){
		char op[10];
		int x;
		scanf("%s",op);
		if(op[0]=='I'){
			scanf("%d",&x);
			insert(x);
		}
		if(op[0]=='M'){
			scanf("%d",&x);
			pos=x+1;
		}
		if(op[0]=='D'){
			scanf("%d",&x);
			del(x);
		}
		if(op[0]=='G'){
			scanf("%d",&x);
			int a=queryrank(pos),b=queryrank(pos+x+1);
			splay(a,0);
			splay(b,a);
			print(ch[b][0]);
			puts(""); 
		}
		if(op[0]=='P') pos--;
		if(op[0]=='N') pos++;
		//splay(pos,0);
//		print(root);
//		puts("");
	}	
	return 0;
}

这是我的代码,我在最后随便加了个 splay 就过了另外两个点。到底该怎么搞,才能保证 splay 复杂度正确。也可能我的代码本身是有问题的

2021/3/25 18:37
加载中...