社区讨论

fhq求助

P3391【模板】文艺平衡树参与者 4已保存回复 9

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
9 条
当前快照
1 份
快照标识符
@lobbjzpv
此快照首次捕获于
2023/10/29 18:19
2 年前
此快照最后确认于
2023/11/04 00:10
2 年前
查看原帖
CPP
#include <bits/stdc++.h>
using namespace std;
const int SIZE = 100005;
int n, m, tot, root;
int ch[SIZE][2], size[SIZE], val[SIZE], rnd[SIZE];
bool tag[SIZE];
int X, Y, Z;

inline int rd(){
	int x = 0, f = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9'){
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9'){
		x = (x<<1)+(x<<3)+(ch^48);
		ch = getchar();
	}
	return x*f;
}

void pushup(int p){
	size[p] = size[ch[p][0]] + size[ch[p][1]] + 1;
}

void pushdown(int p){
	if(tag[p]){
		swap(ch[p][0], ch[p][1]);
		if(ch[p][0]) tag[ch[p][0]] ^= 1;
		if(ch[p][1]) tag[ch[p][1]] ^= 1;
		tag[p] = 0;
	}
}

int New(int x){
	ch[++tot][0] = ch[tot][1] = 0;
	size[tot] = 1; val[tot] = x;
	rnd[tot] = rand();
	return tot;
}

void split(int now, int k, int &x, int &y){
	if(!now) x = y = 0;
	else{
		pushdown(now);
		if(val[now] <= k) x = now, split(ch[now][1], k, ch[now][1], y);
		else y = now, split(ch[now][0], k, x, ch[now][0]);
		pushup(now);
	}	
}

int merge(int A, int B){
	if(!A || !B) return A + B;
	if(rnd[A] < rnd[B]){
		pushdown(A);
		ch[A][1] = merge(ch[A][1], B);
		pushup(A);
		return A;
	}
	else{
		pushdown(B);
		ch[B][0] = merge(A, ch[B][0]);
		pushup(B);
		return B;
	}
}

void change(int l, int r){
	split(root, r, X, Y);
	split(X, l-1, Z, X);
	tag[X] ^= 1;
	root = merge(merge(Z, X), Y);	
}

void Print(int p){
	if(!p) return;
	if(tag[p]) pushdown(p);
	Print(ch[p][0]);
	printf("%d ", val[p]);
	Print(ch[p][1]);
}

int main(){
	srand(time(0));
	n = rd(), m = rd();
	for(int i = 1; i <= n; i++){
		root = merge(root, New(i));
	}
	for(int i = 1; i <= m; i++){
		int l = rd(), r = rd();
		change(l, r);
	}
	Print(root);
	return 0;
}
/*
5 10
1 3
2 4
1 5
2 3
3 5
1 2
2 3
3 4
1 3
1 5
*/

回复

9 条回复,欢迎继续交流。

正在加载回复...