刚学OI,写了个假的可持久化平衡树,怎么改

P3835 【模板】可持久化平衡树

```cpp //巨丑的代码 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #define MN 500005 #define inf 2147483647 #define re register int using namespace std; int son[MN*50][2],val[MN*50],rnd[MN*50],size[MN*50]; int cnt,n,m,root[MN],x,y,z; void pushup(int x){size[x]=size[son[x][0]]+size[son[x][1]]+1;} int add(int x){ val[++cnt]=x; size[cnt]=1; rnd[cnt]=rand(); return cnt; } void split(int now,int k,int &x,int &y){ if(!now)x=y=0; else { if(val[now]<=k) { x=++cnt; val[x]=val[now]; rnd[x]=rnd[now]; size[x]=size[now]; son[x][1]=son[now][1]; son[x][0]=son[now][0]; split(son[x][1],k,son[x][1],y); pushup(x); } else { y=++cnt; val[y]=val[now]; rnd[y]=rnd[now]; size[y]=size[now]; son[y][1]=son[now][1]; son[y][0]=son[now][0]; split(son[y][0],k,x,son[y][0]); pushup(y); } } } int merge(int p,int q){ if(!p||!q)return p+q; if(rnd[p]<rnd[q]){ son[p][1]=merge(son[p][1],q); pushup(p); return p; } else { son[q][0]=merge(p,son[q][0]); pushup(q); return q; } } int kth(int now,int k) { if(k<=size[son[now][0]])return kth(son[now][0],k); else if(k==size[son[now][0]]+1) return now; else {k-=(size[son[now][0]]+1);return kth(son[now][1],k);} } int main(){ scanf("%d",&n); for(re i=1;i<=n;i++){ int a1,a2,a3; scanf("%d%d%d",&a1,&a2,&a3); root[i]=root[a1]; if(a2==1){ split(root[i],a3,x,y); root[i]=merge(merge(x,add(a3)),y); } if(a2==2){ split(root[i],a3,x,z); split(x,a3-1,x,y); y=merge(son[y][0],son[y][1]); root[i]=merge(merge(x,y),z); } if(a2==3){ split(root[i],a3-1,x,y); printf("%d\n",size[x]+1); root[i]=merge(x,y); } if(a2==4){ printf("%d\n",val[kth(root[i],a3)]); } if(a2==5){ split(root[i],a3-1,x,y); if(x)printf("%d\n",val[kth(x,size[x])]); else printf("-2147483647\n"); root[i]=merge(x,y); } if(a2==6){ split(root[i],a3,x,y); if(y)printf("%d\n",val[kth(y,1)]); else printf("2147483647\n"); root[i]=merge(x,y); } } return 0; } ```
by 红色OI再临 @ 2019-07-03 19:10:03


所以如何严格证明merge时不用新建结点呢?
by WAutomaton @ 2019-07-07 12:02:40


上一页 |