3223: Tyvj 1729 文艺平衡树

3223: Tyvj 1729 文艺平衡树

Time Limit: 10 Sec   Memory Limit: 128 MB
Submit: 2466   Solved: 1380
[ Submit][ Status][ Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 

Input

第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n 

Output

 

输出一行n个数字,表示原始序列经过m次变换后的结果 

Sample Input

5 3

1 3

1 3

1 4

Sample Output

4 3 2 1 5

HINT



N,M<=100000

Source

[ Submit][ Status][ Discuss]

splay解决区间问题..
每次操作将l-1转到根r+1转到根的右儿子,这样r+1的左儿子就是[l,r]并上标记
标记需使用xor操作,因为翻转可逆
然后每次插入必须将新插入的点转到根

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;

const int maxn = 1E5 + 10;

int n,m,ans[maxn];

class data{
	private:
		struct Node{
			Node *ch[2];
			int num,mark,siz;
		}*root,*tot,pool[maxn];
		
		void maintain(Node *&x) {
			int s0 = (x->ch[0] == NULL)?0:x->ch[0]->siz;
			int s1 = (x->ch[1] == NULL)?0:x->ch[1]->siz;
			x->siz = s0+s1+1;
		}
		
		void rotate(Node *&x,int d) {
			Node *y = x->ch[d]; //y->fa = x->fa; 
			x->ch[d] = y->ch[d^1]; //y->ch[d^1]->fa = x;
			y->ch[d^1] = x; //x->fa = y;
			maintain(x); 
			x = y; 
			maintain(x);
		}
		
		int Insert(Node *&x,int num) {
			int ret = 0;
			if (x == NULL) {
				x = ++tot;
				x->ch[0] = x->ch[1] = NULL;
				x->num = num; x->siz = 1;
				x->mark = 0; return 1;
			}
			
			int d = (x->num > num)?0:1;
			int s0 = (x->ch[0] == NULL)?0:x->ch[0]->siz;
			ret = s0+1;
			int sum = Insert(x->ch[d],num);
			//x->ch[d]->fa = x;
			maintain(x);
			return ret + sum;
		}
		
		void pushdown(Node *&x) {
			if (x->mark) {
				swap(x->ch[0],x->ch[1]);
				if (x->ch[0] != NULL) x->ch[0]->mark ^= 1;
				if (x->ch[1] != NULL) x->ch[1]->mark ^= 1;
				x->mark = 0;
			}
		}
		
		/*Node* find(Node *x,int rank) {
			pushdown(x);
			int s0 = (x->ch[0] == NULL)?0:x->ch[0]->siz;
			if (s0+1 == rank) return x;
			else if (s0+1 > rank) return find(x->ch[0],rank);
			else return find(x->ch[1],rank-s0-1);
		}*/
		
		void splay(Node *&x,int rank) {
			pushdown(x);
			int s0 = (x->ch[0] == NULL)?0:x->ch[0]->siz;
			if (s0+1 != rank) {
				int d;
				if (s0+1 >= rank) d = 0;
				else d = 1,rank = rank - s0 - 1;
				pushdown(x->ch[d]);
				int s1 = (x->ch[d]->ch[0] == NULL)?0:x->ch[d]->ch[0]->siz;
				if (s1+1 != rank) {
					int d2;
					if (s1+1 >= rank) d2 = 0;
					else d2 = 1,rank = rank - s1 - 1;
					splay(x->ch[d]->ch[d2],rank);
					if (d == d2) rotate(x,d);
					else rotate(x->ch[d],d2);
				}
				rotate(x,d); 
			}
		}
		
		void DFS(Node *x,int sum) {
			pushdown(x);
			int s0 = (x->ch[0] == NULL)?0:x->ch[0]->siz;
			ans[s0+1+sum] = x->num;
			if (x->ch[0] != NULL) DFS(x->ch[0],sum);
			if (x->ch[1] != NULL) DFS(x->ch[1],sum+s0+1);
		}
		
	public:
		data() {
			root = NULL;
			tot = pool;
		}
		
		int Ins(int num) {
			return Insert(root,num);
		}
		
		void setmark() {
			//pushdown(root);
			//pushdown(root->ch[1]);
			root->ch[1]->ch[0]->mark ^= 1;
		}

		void spl(int rank,int typ) {
			if (!typ) splay(root,rank);
			else {
				pushdown(root);
				int s0 = (root->ch[0] == NULL)?0:root->ch[0]->siz;
				splay(root->ch[1],rank-s0-1);
			}
		}
		
		void dfs() { 
			DFS(root,0);
		}
};

int main()
{
	#ifdef YZY
		   freopen("yzy.txt","r",stdin);
	#endif
	
	static data tree;
	cin >> n >> m;
	for (int i = 0; i <= n+1; i++) 
		tree.spl(tree.Ins(i),0);
	//tree.dfs();
	
	while (m--) {
		int l,r;
		scanf("%d%d",&l,&r);
		tree.spl(l,0); 
		tree.spl(r+2,1);
		tree.setmark();
		//tree.dfs();
	}
	
	tree.dfs();
	for (int i = 2; i <= n+1; i++) {
		printf("%d ",ans[i]);
	}
	
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值