【BZOJ3223】【TYVJ1729】—文艺平衡树(FHQ_Treap)
传送门
平衡树区间操作板子
直接敲就是了
注意
#include<bits/stdc++.h>
using namespace std;
#define ll long long
inline int read(){
char ch=getchar();
int res=0,f=1;
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
return res*f;
}
const int N=100005;
int n,m,rt,son[N][2],val[N],siz[N],key[N],rev[N],tot;
#define lc(u) son[u][0]
#define rc(u) son[u][1]
inline int rnd(){
return ((rand()<<10)^rand());
}
inline int addnode(int k){
val[++tot]=k,siz[tot]=1,key[tot]=rnd();return tot;
}
inline void pushup(int u){
siz[u]=siz[lc(u)]+siz[rc(u)]+1;
}
inline void pushdown(int u){
if(!rev[u])return;
swap(lc(u),rc(u));
rev[lc(u)]^=1;
rev[rc(u)]^=1;
rev[u]=0;
}
inline void split(int u,int &r1,int &r2,int k){
if(!u){r1=r2=0;return;}
pushdown(u);
if(siz[lc(u)]>=k){
r2=u,split(lc(u),r1,lc(r2),k);
}
else{
r1=u,split(rc(u),rc(r1),r2,k-siz[lc(u)]-1);
}
pushup(u);
}
inline void merge(int &u,int r1,int r2){
if(!r1||!r2){u=r1+r2;return;}
if(key[r1]<key[r2]){
pushdown(r1);
u=r1,merge(rc(u),rc(r1),r2);
}
else{
pushdown(r2);
u=r2,merge(lc(u),r1,lc(r2));
}
pushup(u);
}
inline void insert(int k){
int r1=0,r2=0,u;
u=addnode(k);
merge(rt,rt,u);
}
inline void reverse(int l,int r){
int r1=0,r2=0,r3=0;
split(rt,r1,r2,l-1);
split(r2,r2,r3,r-l+1);
rev[r2]^=1,merge(r2,r2,r3);
merge(rt,r1,r2);
}
void write(int u){
pushdown(u);
if(lc(u))write(lc(u));
cout<<val[u]<<" ";
if(rc(u))write(rc(u));
}
int main(){
srand(time(NULL));
n=read(),m=read();
for(int i=1;i<=n;i++){
insert(i);
}
for(int i=1;i<=m;i++){
int l=read(),r=read();
reverse(l,r);
}
write(rt);
}