ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Splay 区间翻转 & 区间移位 - HDU3487 - Play with Chain

2021-03-15 11:36:03  阅读:140  来源: 互联网

标签:rt Play suc Chain int tr down push 区间


#include <bits/stdc++.h>
using namespace std;

const int N = 3e5+10;
const int INF = 0x3fffffff;
int first = 1;
int n, m, a, b, c;
int rt;
char op[10];
int arr[N];

struct Node{
	int s[2], v, p;
	int lazy;
	int size;
	void init(int _s0, int _s1, int _v, int _p){
		s[0] = _s0;
		s[1] = _s1;
		v = _v;
		p = _p;
		lazy = 0;
		size = 1;
	}
}tr[N];

void push_up(int x){
	tr[x].size = tr[tr[x].s[0]].size + tr[tr[x].s[1]].size + 1;
}

void push_down(int x){
	if(tr[x].lazy){
		swap(tr[x].s[0], tr[x].s[1]);
		if(tr[x].s[0]) tr[tr[x].s[0]].lazy ^= 1;
		if(tr[x].s[1]) tr[tr[x].s[1]].lazy ^= 1;
		tr[x].lazy = 0;
	}
}

int build(int l, int r, int p){
	if(l > r) return 0;
	else if(l == r){
		tr[l].init(0, 0, arr[l], p);
		return l;
	}else{
		int mid = l+r>>1;
		tr[mid].init
			(
			build(l, mid-1, mid), 
			build(mid+1, r, mid), 
			arr[mid], 
			p
			);

		push_up(mid);
		return mid;
	}
}

int ws(int x){
	return tr[tr[x].p].s[1] == x;
}

void rotate(int x){
	int y = tr[x].p;
	int z = tr[y].p;
	push_down(y);
	push_down(x);
	int k = ws(x);
	// modify z
	tr[z].s[ws(y)] = x;
	// modify y
	tr[y].p = x;
	tr[y].s[k] = tr[x].s[k^1];
	// modify m
	tr[tr[x].s[k^1]].p = y;
	// modify x
	tr[x].p = z;
	tr[x].s[k^1] = y;

	push_up(y);
	push_up(x);
}

void splay(int x, int k){
	while(tr[x].p != k){
		int y = tr[x].p;
		int z = tr[y].p;

		push_down(z);
		push_down(y);
		push_down(x);
		
		if(z != k){
			if(ws(x) ^ ws(y)){
				rotate(x);
			}else{
				rotate(y);
			}
		}
		rotate(x);
	}

	if(!k) rt = x;
}


int get_k(int k){
	int u = rt;
	while(u){
		push_down(u);
		if(tr[tr[u].s[0]].size >= k){
			u = tr[u].s[0];
		}else if(tr[tr[u].s[0]].size + 1 == k){
			return u;
		}else{
			k -= tr[tr[u].s[0]].size + 1;
			u = tr[u].s[1];
		}
	}
	return -1;
}


int split(int l, int r){
	l = get_k(l);
	r = get_k(r+2);
	splay(l, 0);
	splay(r, l);
	return tr[r].s[0];
}

void output(int rt){
	push_down(rt);
	if(tr[rt].s[0]) output(tr[rt].s[0]);
	if(tr[rt].v != INF){
		if(first) first = 0; else putchar(' ');
		printf("%d", tr[rt].v);
	}
	if(tr[rt].s[1]) output(tr[rt].s[1]);
}
int main(){
	for(int i = 2; i < N; ++i){
		arr[i] = i-1;
	}
	arr[1] = INF;
	while(scanf("%d%d", &n, &m)){
		if(n < 0 && m < 0){
			break;
		}
		arr[n+2] = INF;
		rt = build(1, n+2, 0);
		while(m--){
			scanf("%s", op);
			if(*op == 'C'){
				scanf("%d%d%d", &a, &b, &c);

				int u = split(a, b);
				tr[tr[u].p].s[ws(u)] = 0; // cut
				
				int pre = get_k(c+1);
				splay(pre, 0);
				push_down(pre);
				int suc = tr[pre].s[1];
				push_down(suc);
				while(tr[suc].s[0]){
					suc = tr[suc].s[0];
					push_down(suc);
				}
				splay(suc, pre);

				tr[suc].s[0] = u; // connect
				tr[u].p = suc;
                
				push_up(suc);
				push_up(pre);
			}else{
				scanf("%d%d", &a, &b);
				int u = split(a, b);
				tr[u].lazy ^= 1;
			}
		}
		output(rt);
		arr[n+2] = n+1;
		first = 1;
		putchar('\n');
	}

	system("pause");
	return 0;
}

标签:rt,Play,suc,Chain,int,tr,down,push,区间
来源: https://www.cnblogs.com/popodynasty/p/14536585.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有