文艺平衡树

#include<cstdio>
#include<algorithm>
#include<ctime>
using namespace std;
int n,m,root,tot = 0;

struct tree{
	int ls,rs,v,siz,rnd,tag;
}tr[100005];
int add(int val)
{
	tr[++tot] = (tree){0,0,val,1,rand(),0};
	return tot;
}
void update(int x){tr[x].siz = tr[tr[x].ls].siz + tr[tr[x].rs].siz + 1;}
void pushdown(int x)
{
	if (!x || !tr[x].tag) return;
	swap(tr[x].ls,tr[x].rs),tr[x].tag = 0;
	if (tr[x].ls) tr[tr[x].ls].tag ^= 1;
	if (tr[x].rs) tr[tr[x].rs].tag ^= 1;
}
void build(int &rt,int l,int r)
{
	if (l > r) return void(rt = 0);
	int mid = l + r >> 1;
	rt = add(mid);
	build(tr[rt].ls,l,mid - 1),build(tr[rt].rs,mid + 1,r);
	update(rt);
}
void split(int rt,int &x,int &y,int k)
{
	if (!rt) return void(x = y = 0);
	pushdown(rt);
	if (k <= tr[tr[rt].ls].siz) y = rt,split(tr[rt].ls,x,tr[y].ls,k);
	else x = rt,split(tr[rt].rs,tr[x].rs,y,k - tr[tr[rt].ls].siz - 1);
	update(rt);
}
void merge(int &rt,int x,int y)
{
	if (!x || !y) return void(rt = x + y);
	pushdown(x),pushdown(y);
	if (tr[x].rnd < tr[y].rnd) rt = x,merge(tr[rt].rs,tr[x].rs,y);
	else rt = y,merge(tr[rt].ls,x,tr[y].ls);
	update(rt);
}
void reverse(int &rt,int l,int r)
{
	int x = 0,y = 0,z = 0;
	split(rt,x,y,r),split(x,x,z,l - 1);
	tr[z].tag ^= 1,merge(x,x,z),merge(rt,x,y);
}
void dfs(int rt)
{
	if (!rt) return;
	pushdown(rt);
	dfs(tr[rt].ls);
	printf("%d ",tr[rt].v);
	dfs(tr[rt].rs);
} 
int main()
{
	srand(time(NULL));
	scanf("%d%d",&n,&m);
	build(root,1,n);
	for (int i = 1,q,p; i <= m; i++)
		scanf("%d%d",&q,&p),reverse(root,q,p);
	dfs(root);
}
上一篇:P3380 【模板】二逼平衡树(树套树)


下一篇:P2234 [HNOI2002]营业额统计【Splay】