MnZn刚学OI,样例过了爆零,求助
查看原帖
MnZn刚学OI,样例过了爆零,求助
434929
Usada_Pekora楼主2022/2/25 09:31
#include <bits/stdc++.h>
using namespace std;
const int N = 2e6 + 5;
int val[N], cnt, size[N], pri[N], ls[N], rs[N], tag[N], n, q, rt;
inline int build(int w) {
	val[++cnt] = w;
	pri[cnt] = rand();
	size[cnt] = 1;
	return cnt;
}
inline void pushup(int p) {
	size[p] = size[ls[p]] + size[rs[p]] + 1;
}
inline void pushdown(int p) {
	if(!tag[p]) return;
	swap(ls[p], rs[p]);
	if(ls[p]) tag[ls[p]] ^= 1;
	if(rs[p]) tag[rs[p]] ^= 1;
	tag[p] = 0;
}
inline void split(int p, int siz, int &x, int &y) {
	if(!p) {
		x = y = 0;
		return;
	}
	pushdown(p);
	if(size[ls[p]] + 1 <= siz) {
		x = p;
		split(rs[p], siz - size[ls[p]] - 1, rs[p], y);
	} else {
		y = p;
		split(ls[p], siz, x, ls[p]);
	}
	pushup(p);
}
inline int merge(int x, int y) {
	if(!x || !y) return x + y;
	if(pri[x] > pri[y]) {
		pushdown(x);
		rs[x] = merge(rs[x], y);
		pushup(x);
		return x;
	} else {
		pushdown(y);
		ls[y] = merge(x, ls[y]);
		pushup(y);
		return y;
	}
}
inline void insert(int pos, int w) {
	int x, y;
	split(rt, pos - 1, x, y);
	rt = merge(merge(x, build(w)), y);
}
inline void flip(int l, int r) {
	int x, y, z;
	split(rt, l - 1, x, y);
	split(y, r, y, z);
	tag[y] ^= 1;
	rt = merge(merge(x, y), z);
}
inline void print(int p) {
	pushdown(p);
	if(ls[p]) print(ls[p]);
	printf("%d ", val[p]);
	if(rs[p]) print(rs[p]);
}
int main() {
	srand(time(NULL) * 1u);
	int l, r;
	scanf("%d%d", &n, &q);
	for(int i = 1; i <= n; i++) insert(i, i);
	for(int i = 1; i <= q; i++) {
		scanf("%d%d", &l, &r);
		flip(l, r);
	}
	print(rt);
	return 0;
} 
2022/2/25 09:31
加载中...