UVA11922 Permutation Transformer 题解

题目传送门

前置知识

无旋 treap

解法

luogu P3391 【模板】文艺平衡树 不同的是本题翻转后需要放到整个序列的末尾。

由于需要翻转后放到末尾,故无旋 Treap 在维护文艺平衡树的过程中合并时跳着合并即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'
struct BST
{
	const int INF=0x7f7f7f7f;
	int rt_sum,root;
	struct FHQ_Treap
	{
		int son[2],val,rnd,cnt,siz,lazy;
	}tree[100010];
	#define lson(rt) (tree[rt].son[0])
	#define rson(rt) (tree[rt].son[1])
	BST()
	{
		rt_sum=root=0;
		srand(time(0));
	}
	void pushup(int rt)
	{
		tree[rt].siz=tree[lson(rt)].siz+tree[rson(rt)].siz+tree[rt].cnt;
	}
	int build(int val)
	{
		rt_sum++;
		lson(rt_sum)=rson(rt_sum)=tree[rt_sum].lazy=0;
		tree[rt_sum].val=val;
		tree[rt_sum].rnd=rand();
		tree[rt_sum].cnt=tree[rt_sum].siz=1;
		return rt_sum;
	}
	void pushdown(int rt)
	{
		if(rt!=0&&tree[rt].lazy!=0)
		{
			swap(lson(rt),rson(rt));
			tree[lson(rt)].lazy^=1;
			tree[rson(rt)].lazy^=1;
			tree[rt].lazy=0;
		}
	}
	void split(int rt,int k,int &ls,int &rs)
	{
		if(rt==0)
		{
			ls=rs=0;
			return;
		}
		pushdown(rt);
		if(tree[lson(rt)].siz+tree[rt].cnt<=k)
		{
			ls=rt;
			split(rson(ls),k-tree[lson(rt)].siz-tree[rt].cnt,rson(ls),rs);
		}
		else
		{
			rs=rt;
			split(lson(rs),k,ls,lson(rs));
		}
		pushup(rt);
	}
	int merge(int rt1,int rt2)
	{
		if(rt1==0||rt2==0)
		{
			return rt1+rt2;
		}
		if(tree[rt1].rnd<tree[rt2].rnd)
		{
			pushdown(rt1);
			rson(rt1)=merge(rson(rt1),rt2);
			pushup(rt1);
			return rt1;
		}
		else
		{
			pushdown(rt2);
			lson(rt2)=merge(rt1,lson(rt2));
			pushup(rt2);
			return rt2;
		}
	}
	void insert(int val)
	{
		int ls,rs;
		split(root,val,ls,rs);
		root=merge(merge(ls,build(val)),rs);
	}
	void reverse(int l,int r)
	{
		int ls,rs,mid;
		split(root,r,ls,rs);
		split(ls,l-1,ls,mid);
		tree[mid].lazy^=1;
		root=merge(merge(ls,rs),mid);
	}
	void inorder(int rt)
	{
		if(rt!=0)
		{
			pushdown(rt);
			inorder(lson(rt));
			cout<<tree[rt].val<<endl;
			inorder(rson(rt));
		}
	}
}T;
int main()
{
	int n,m,l,r,i;
	cin>>n>>m;
	for(i=1;i<=n;i++)
	{
		T.insert(i);
	}
	for(i=1;i<=m;i++)
	{
		cin>>l>>r;
		T.reverse(l,r);
	}
	T.inorder(T.root);
	return 0;
}
posted @ 2024-05-26 11:21  hzoi_Shadow  阅读(4)  评论(0编辑  收藏  举报
扩大
缩小