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

#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;
}
上一篇:Filter过滤器输出HelloFilter


下一篇:读书笔记--C陷阱与缺陷(六)