求问,悬关
  • 板块学术版
  • 楼主Walrus
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/7/12 11:19
  • 上次更新2024/7/12 11:51:34
查看原帖
求问,悬关
908424
Walrus楼主2024/7/12 11:19

rt,在 P3391 写 fhq 时 code 输出的答案每次在 rand 的变化下也会跟着变化,这种情况是为啥?如何解决?

#include <bits/stdc++.h>
#define int long long
#define rep(i, j, k) for(int i = j; i <= k; ++i)
#define pb push_back
using namespace std;

const int N = 4e5 + 5;

int cnt, rt;

struct node {
	int l, r;
	int key, val;
	int siz, tag;

#define l(p) t[p].l
#define r(p) t[p].r
#define key(p) t[p].key
#define val(p) t[p].val
#define siz(p) t[p].siz
#define tag(p) t[p].tag
} t[N];

#define ls (p << 1)
#define rs (p << 1 | 1)


void pushup(int p) {
	siz(p) = siz(l(p)) + siz(r(p)) + 1;
}

void pushdown(int p) {
	if(tag(p)) {
		swap(l(p), r(p));
		tag(l(p)) ^= 1, tag(r(p)) ^= 1;
		tag(p) = 0;
	}
}

int get_node(int val) {
	int p = ++cnt;
	key(p) = val;
	val(p) = rand();
	siz(p) = 1;
	return p;
}

void split(int p, int key, int &x, int &y) {
	if(p == 0)
		return x = y = 0, void();
	pushdown(p);
	if(key(p) <= key)
		x = p, split(r(p), key, r(p), y);
	else
		y = p, split(l(p), key, x, l(y));
	pushup(p);
}

int merge(int x, int y) {
	if(!x || !y) return x + y;
	if(val(x) >= val(y))
		return pushdown(x), r(x) = merge(r(x), y), pushup(x), x;
	else
		return pushdown(y), l(y) = merge(x, l(y)), pushup(y), y;
}

void insert(int key) {
	int x, y;
	split(rt, key - 1, x, y);
	int p = get_node(key);
	rt = merge(merge(x, p), y);
}

void remove(int key) {
	int x, y, z;
	split(rt, key - 1, x, y), split(y, key, y, z);
	if(y) y = merge(l(y), r(y));
	rt = merge(merge(x, y), z);
}

int rank(int key) {
	int x, y, res;
	split(rt, key - 1, x, y);
	res = siz(x) + 1;
	rt = merge(x, y);
	return res;
}

int value(int val) {
	int p = rt;
	while(p) {
		if(siz(l(p)) + 1 == val) break;
		else if(siz(l(p)) + 1 > val) p = l(p);
		else  {
			val -= siz(l(p)) + 1, p = r(p);
		}
	}
	return key(p);
}

int get_pre(int key) {
	int x, y, p;
	split(rt, key - 1, x, y);
	p = x;
	while(r(p)) p = r(p);
	rt = merge(x, y);
	return key(p);
}

int get_nxt(int key) {
	int x, y, p;
	split(rt, key, x, y);
	p = y;
	while(l(p)) p = l(p);
	rt = merge(x, y);
	return key(p);
}

void reverse(int l, int r) {
	int x = 0, y = 0, z = 0;
	split(rt, l - 1, x, y), split(y, r - l + 1, y, z);
	tag(y) ^= 1;
	rt = merge(merge(x, y), z);
}

void print(int p) {
	if(!p) return;
	pushdown(p);
	print(l(p));
	cout << key(p) << ' ';
	print(r(p));
}



int n, q, op, x, l, r;

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(nullptr), cout.tie(nullptr);

	srand(time(0));

	freopen("std.in", "r", stdin);

	cin >> n >> q;
	rep(i, 1, n) rt = merge(rt, get_node(i));
	cout << rt << '\n';
	while(q--) cin >> l >> r, reverse(l, r);
	
	print(rt);

	return 0;
}
2024/7/12 11:19
加载中...