社区讨论
求助,这种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 条回复,欢迎继续交流。
正在加载回复...