[luogu3835]可持久化平衡树

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu3835]可持久化平衡树相关的知识,希望对你有一定的参考价值。

就是把普通平衡树的代码可持久化一下

第一发90,最后两个点MLE???这是什么操作

后来把能非递归的都改成非递归,结果TLE???这又是什么操作

最后发现我才用了内存限制的一半,改大一点之后过掉倒数第二个点,再改大一点就A掉了

所以TLE是什么鬼啊

技术分享图片

之前立了个用指针的flag,结果这题指针版会MLE......

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int l[25000000],r[25000000],v[25000000],siz[25000000],fix[25000000],rt[500010],stk[500010],top,tot;
void update(int x){siz[x]=siz[l[x]]+siz[r[x]]+1;}
struct pair{
	int l,r;
	pair(int a=0,int b=0){l=a;r=b;}
};
int newnode(int d){
	int x;
	if(top){
		x=stk[top];
		top--;
	}else
		x=++tot;
	v[x]=d;
	l[x]=r[x]=0;
	siz[x]=1;
	fix[x]=rand()*rand();
	return x;
}
int copy(int u){
	int x;
	if(top){
		x=stk[top];
		top--;
	}else
		x=++tot;
	v[x]=v[u];
	l[x]=l[u];
	r[x]=r[u];
	siz[x]=siz[u];
	fix[x]=fix[u];
	return x;
}
pair split(int x,int k){
	if(x==0)return pair();
	if(k==0)return pair(0,copy(x));
	if(k==siz[x])return pair(copy(x),0);
	pair s;
	int n=copy(x);
	if(k<=siz[l[x]]){
		s=split(l[n],k);
		l[n]=s.r;
		s.r=n;
	}else{
		s=split(r[n],k-siz[l[x]]-1);
		r[n]=s.l;
		s.l=n;
	}
	update(n);
	return s;
}
int merge(int x,int y){
	if(x==0&&y==0)return 0;
	if(x==0)return copy(y);
	if(y==0)return copy(x);
	int n;
	if(fix[x]<fix[y]){
		n=copy(x);
		r[n]=merge(r[n],y);
	}else{
		n=copy(y);
		l[n]=merge(x,l[n]);
	}
	update(n);
	return n;
}
bool find(int x,int d){
	while(x){
		if(d==v[x])return 1;
		if(d<v[x])
			x=l[x];
		else
			x=r[x];
	}
	return 0;
}
int lt(int x,int d){
	int s=0;
	while(x){
		if(d<=v[x])
			x=l[x];
		else{
			s+=siz[l[x]]+1;
			x=r[x];
		}
	}
	return s;
}
int getkth(int x,int k){
	while(k!=siz[l[x]]+1){
		if(k<=siz[l[x]])
			x=l[x];
		else{
			k-=siz[l[x]]+1;
			x=r[x];
		}
	}
	return v[x];
}
#define inf 2147483647
int presc(int x,int d){
	int ans=-inf;
	while(x){
		if(v[x]<d){
			ans=v[x];
			x=r[x];
		}else
			x=l[x];
	}
	return ans;
}
int nexsc(int x,int d){
	int ans=inf;
	while(x){
		if(v[x]>d){
			ans=v[x];
			x=l[x];
		}else
			x=r[x];
	}
	return ans;
}
int main(){
	srand(time(0));
	int i,m,v,o,x;
	pair s,t;
	scanf("%d",&m);
	for(i=1;i<=m;i++){
		scanf("%d%d%d",&v,&o,&x);
		if(o==1){
			s=split(rt[v],lt(rt[v],x));
			rt[i]=merge(s.l,merge(newnode(x),s.r));
		}
		if(o==2){
			if(find(rt[v],x)){
				s=split(rt[v],lt(rt[v],x));
				t=split(s.r,1);
				rt[i]=merge(s.l,t.r);
				top++;
				stk[top]=t.l;
			}else
				rt[i]=rt[v];
		}
		if(o==3){
			printf("%d\\n",lt(rt[v],x)+1);
			rt[i]=rt[v];
		}
		if(o==4){
			printf("%d\\n",getkth(rt[v],x));
			rt[i]=rt[v];
		}
		if(o==5){
			printf("%d\\n",presc(rt[v],x));
			rt[i]=rt[v];
		}
		if(o==6){
			printf("%d\\n",nexsc(rt[v],x));
			rt[i]=rt[v];
		}
	}
}

以上是关于[luogu3835]可持久化平衡树的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P3835 模板可持久化平衡树

洛谷P3835 模板可持久化平衡树

luogu P3919 [模板]可持久化数组(可持久化线段树/平衡树)(主席树)

[Luogu 3919]模板可持久化数组(可持久化线段树/平衡树)

Luogu5055 模板可持久化文艺平衡树(fhq-treap)

可持久化平衡树