[luogu3391] 模板文艺平衡树(fhq-treap反转区间)
Posted elpsycongroo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu3391] 模板文艺平衡树(fhq-treap反转区间)相关的知识,希望对你有一定的参考价值。
解题关键:无旋treap模板。
#include<iostream> #include<cstdio> #include<cstring> #include<ctime> #include<cstdlib> #include<cmath> #include<algorithm> #define maxn 500001 using namespace std; typedef long long ll; int size[maxn],ch[maxn][2],rnd[maxn],val[maxn],rev[maxn]; int ncnt,x,y,z,rt,n,m; inline void pushup(int x){ size[x]=1+size[ch[x][0]]+size[ch[x][1]]; } inline void pushdown(int rt){ if(rev[rt]){ swap(ch[rt][0],ch[rt][1]); if(ch[rt][0]) rev[ch[rt][0]]^=1; if(ch[rt][1]) rev[ch[rt][1]]^=1; rev[rt]=0; } } inline int new_node(int x){ size[++ncnt]=1; val[ncnt]=x; rnd[ncnt]=rand(); return ncnt; } //核心 int merge(int A,int B){ if(!A||!B) return A+B; if(rnd[A]<rnd[B]){pushdown(A);ch[A][1]=merge(ch[A][1],B);pushup(A);return A;} else {pushdown(B);ch[B][0]=merge(A,ch[B][0]);pushup(B);return B;} } //权值分裂 /* void split(int now,int k,int &x,int &y){ if(!now) x=y=0; else{ pushdown(now); if(val[now]<=k) x=now,split(ch[now][1],k,ch[now][1],y); else y=now,split(ch[now][0],k,x,ch[now][0]); pushup(now); } } */ //排名分裂 void split(int now,int k,int &x,int &y){ if(!now) x=y=0; else{ pushdown(now); if(k<=size[ch[now][0]]){y=now;split(ch[now][0],k,x,ch[now][0]);} else{x=now;split(ch[now][1],k-size[ch[now][0]]-1,ch[now][1],y);} pushup(now); } } void insert(int &k,int a){ split(k,a,x,y); k=merge(merge(x,new_node(a)),y); } void reverse(int &k,int l,int r){ split(k,l-1,x,y); split(y,r-l+1,y,z); rev[y]^=1; k=merge(x,merge(y,z)); } void print(int &k){ if(!k) return; pushdown(k); print(ch[k][0]); if(val[k]>=1&&val[k]<=n) printf("%d ",val[k]); print(ch[k][1]); } int main(){ srand(time(0)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) insert(rt,i); for(int i=1,l,r;i<=m;i++){ scanf("%d%d",&l,&r); reverse(rt,l,r); } print(rt); return 0; }
以上是关于[luogu3391] 模板文艺平衡树(fhq-treap反转区间)的主要内容,如果未能解决你的问题,请参考以下文章