【BZOJ3223】【TYVJ1729】—文艺平衡树(FHQ_Treap)

传送门
平衡树区间操作板子

直接敲就是了
注意pushdownpushuppushdown,pushup

#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);
}
posted @ 2019-02-13 10:05  Stargazer_cykoi  阅读(156)  评论(0编辑  收藏  举报