社区讨论

求助,这种FHQ与普通的有什么区别

P5055【模板】可持久化文艺平衡树参与者 4已保存回复 8

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
8 条
当前快照
1 份
快照标识符
@locl4m1v
此快照首次捕获于
2023/10/30 15:35
2 年前
此快照最后确认于
2023/11/05 02:45
2 年前
查看原帖
机房学长推荐使用这种随机化:
CPP
#include<bits/stdc++.h>
using namespace std;
int n,v,k,x,y,tot=0,root,last=0;
int rt[2000100];
struct node{
	int val,sum,l,r,siz,tag;
}a[20000000];
int newnode(int x){
	tot++;
	a[tot].val=a[tot].sum=x;
	a[tot].l=a[tot].r=0;
	a[tot].siz=1;
	a[tot].tag=0;
	return tot;
}
void cpy(int &x,int y){
	x=++tot;
	a[x]=a[y];
}
void pushdown(int now){
	if(a[now].tag==0) return;
	int x,y;
	if(a[now].r) cpy(x,a[now].r);
	if(a[now].l) cpy(y,a[now].l);
	a[now].l=x,a[now].r=y;
	a[now].tag^=1;
	if(a[now].l) a[a[now].l].tag^=1;
	if(a[now].r) a[a[now].r].tag^=1;
}
void pushup(int now){a[now].siz=a[a[now].l].siz+a[a[now].r].siz+1;a[now].sum=a[a[now].l].sum+a[a[now].r].sum+a[now].val;}
void split(int now,int k,int &atl,int &atr){
//	cout<<now<<" "<<a[a[now].l].siz+1<<" "<<k<<" "<<a[now].l<<" "<<a[a[now].l].val<<" "<<a[now].r<<" "<<a[a[now].r].val<<endl; 
	int x;
	if(!now){
		atl=atr=0;return;
	}
	pushdown(now);
	if(a[a[now].l].siz<k){
		cpy(atl,now);
//		cout<<atl<<" "<<a[atl].r<<" afdasdfa "<<a[now].r<<endl;
		split(a[atl].r,k-a[a[now].l].siz-1,a[atl].r,atr);
		pushup(atl);
	}
	else{
		cpy(atr,now);
//		cout<<atr<<" "<<a[atr].l<<" onojnklmni "<<a[now].l<<endl;
		split(a[atr].l,k,atl,a[atr].l);
		pushup(atr);
	}
}
int merge(int nl,int nr){
	int x;
	if(!nl||!nr) return nl+nr;
	cout<<endl; 
	if(rand()%(a[nl].siz+a[nr].siz)<a[nl].siz){
		cpy(x,nl);
		pushdown(x); 
		a[x].r=merge(a[x].r,nr);
		pushup(x);
		return x;
	}
	else{
		cpy(x,nr);
		pushdown(x);
		a[x].l=merge(nl,a[x].l);
		pushup(x);
		return x;
	}
}
void print(int now){
	if(!now) return;
	print(a[now].l);
	cout<<a[now].val<<" "<<a[now].tag<<endl;;
	print(a[now].r); 
}
int main(){
	int b,c,d;
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&v,&k);
		rt[i]=rt[v];
		if(k==1){
			scanf("%d%d",&x,&y);
			x^=last,y^=last;
//			cout<<v<<" "<<k<<" "<<x<<" "<<y<<endl;
			split(rt[i],x,b,c);
			rt[i]=merge(merge(b,newnode(y)),c);
		}
		else if(k==2){
			scanf("%d",&x);
			x^=last;
//			cout<<v<<" "<<k<<" "<<x<<endl;
			split(rt[i],x-1,b,c);split(c,1,c,d);
			rt[i]=merge(b,d);
		}
		else if(k==3){
			scanf("%d%d",&x,&y);
			x^=last,y^=last;
//			cout<<v<<" "<<k<<" "<<x<<" "<<y<<endl;
			split(rt[i],y,c,d);split(c,x-1,b,c);
//			printf("%d %d %d\n",a[b].val,a[c].val,a[d].val);
//			print(c),puts("");
			a[c].tag^=1;
//			printf("%d %d %d %d\n",a[c].val,a[c].tag,a[a[c].l].val,a[a[c].r].val);
			rt[i]=merge(merge(b,c),d);
		}
		else{
			scanf("%d%d",&x,&y);
			x^=last,y^=last;
//			cout<<v<<" "<<k<<" "<<x<<" "<<y<<endl;
//			print(rt[i]);puts("");
			split(rt[i],y,c,d);split(c,x-1,b,c);
//			print(b),puts(""),print(c),puts(""),print(d);
			printf("%d\n",a[c].sum);
			last=a[c].sum;
			rt[i]=merge(merge(b,c),d);
		}
//		print(rt[i]);puts("");
	}
	return 0;
}
(不同在于merge的判断条件)
然后我用普通的赋key值A了,但是有同学用学长的做法调了两天还有各种玄学错误。但是事实上普通平衡树上市没有任何问题。
跪求大佬调试,

回复

8 条回复,欢迎继续交流。

正在加载回复...