求助! FHQ Treap一直爆 0, 本地对拍和 DarkBZOJ上均过
查看原帖
求助! FHQ Treap一直爆 0, 本地对拍和 DarkBZOJ上均过
230933
Tony102楼主2021/5/28 15:50

rt,求大神教/kk /wq 不胜感激!

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

const int SIZE = 2e5 + 5;
const int SIZE_T = 2e6 + 5;

int n, q, root, tim;
char str[SIZE], opt[20];

struct node {
	int siz, val, sum, tar, premi, premx, sufmi, sufmx, tag1, tag2, tag3, son[2];
} t[SIZE_T];

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

mt19937 myrand(time(NULL));
#define lson(p) t[p].son[0]
#define rson(p) t[p].son[1]

int addNode(int x) {
	t[++ tim].val = t[tim].sum = x;
	if (x == 1) t[tim].premx = t[tim].sufmx = 1;
	else t[tim].sufmi = t[tim].premi = -1;
	t[tim].siz = 1, t[tim].tar = myrand();
	return tim;
}

void pushUp(int p) {
	t[p].sum = t[lson(p)].sum + t[p].val + t[rson(p)].sum;
	t[p].siz = t[lson(p)].siz + 1 + t[rson(p)].siz;
	t[p].premi = std::min(t[lson(p)].premi, t[lson(p)].sum + t[p].val + t[rson(p)].premi);
	t[p].premx = std::max(t[lson(p)].premx, t[lson(p)].sum + t[p].val + t[rson(p)].premx);
	t[p].sufmi = std::min(t[rson(p)].sufmi, t[rson(p)].sum + t[p].val + t[lson(p)].sufmi);
	t[p].sufmx = std::max(t[rson(p)].sufmx, t[rson(p)].sum + t[p].val + t[lson(p)].sufmx);
}

void pushDownIv(int p) {
	t[p].val *= -1, t[p].sum *= -1;
	std::swap(t[p].premi, t[p].premx); t[p].premi *= -1, t[p].premx *= -1;
	std::swap(t[p].sufmi, t[p].sufmx); t[p].sufmi *= -1, t[p].sufmx *= -1;
	t[p].tag1 ^= 1, t[p].tag2 *= -1;
}

void pushDownCover(int p, int opt) {
	t[p].tag2 = t[p].val = opt, t[p].sum = opt * t[p].siz;
	if (opt == 1) t[p].premi = t[p].sufmi = 0, t[p].sufmx = t[p].premx = t[p].sum;
	else if (opt == -1) t[p].premi = t[p].sufmi = t[p].sum, t[p].premx = t[p].sufmx = 0;
}

void pushDownSwap(int p) {
	std::swap(lson(p), rson(p));
	std::swap(t[p].premi, t[p].sufmi); std::swap(t[p].premx, t[p].sufmx);
	t[p].tag3 ^= 1;
}

void pushDown(int p) {
	if (t[p].tag1) {
		if (lson(p)) pushDownIv(lson(p));
		if (rson(p)) pushDownIv(rson(p));
		t[p].tag1 = 0;
	}
	if (t[p].tag2) {
		if (lson(p)) pushDownCover(lson(p), t[p].tag2);
		if (rson(p)) pushDownCover(rson(p), t[p].tag2);
		t[p].tag2 = 0;
	}
	if (t[p].tag3) {
		if (lson(p)) pushDownSwap(lson(p));
		if (rson(p)) pushDownSwap(rson(p));
		t[p].tag3 = 0;
	}
}

void split(int p, int k, int &ls, int &rs) {
	pushDown(p);
	if (!p) return ls = rs = 0, void();
	if (t[lson(p)].siz + 1 <= k) { ls = p; split(rson(ls), k - t[lson(ls)].siz - 1, rson(ls), rs); }
	else { rs = p; split(lson(rs), k, ls, lson(rs)); }
	pushUp(p);
}

int merge(int ls, int rs) {
	pushDown(ls), pushDown(rs);
	if (!ls || !rs) return ls + rs;
	if (t[ls].tar < t[rs].tar) { rson(ls) = merge(rson(ls), rs); pushUp(ls); return ls; }
	else { lson(rs) = merge(ls, lson(rs)); pushUp(rs); return rs; } 
}

void dfs(int p) {
	if (lson(p)) dfs(lson(p));
	printf("%c", t[p].val == -1 ? '(' : ')');
	if (rson(p)) dfs(rson(p));
}

int main() {
	// freopen("code.in", "r", stdin);
	// freopen("my.out", "w", stdout);
	scanf("%d %d", &n, &q); scanf("%s", str + 1);
	int x, y, z, l, r, ch;
	for (int i = 1; i <= n; ++ i) {
		root = merge(root, addNode(str[i] == '(' ? -1 : 1));
	}
	while (q --) {
		scanf("%s", opt);
		if (opt[0] == 'R') {
			scanf("%d %d %s", &l, &r, opt);
			int v = opt[0] == '(' ? -1 : 1;
			split(root, l - 1, x, y), split(y, r - l + 1, y, z);
			pushDownCover(y, v); root = merge(merge(x, y), z);
		}
		if (opt[0] == 'S') {
			scanf("%d %d", &l, &r);
			split(root, l - 1, x, y), split(y, r - l + 1, y, z);
			pushDownSwap(y); root = merge(merge(x, y), z);
		}
		if (opt[0] == 'I') {
			scanf("%d %d", &l, &r);
			split(root, l - 1, x, y), split(y, r - l + 1, y, z);
			pushDownIv(y); root = merge(merge(x, y), z);
		}
		if (opt[0] == 'Q') {
			scanf("%d %d", &l, &r);
			split(root, l - 1, x, y), split(y, r - l + 1, y, z);
			int pre = 0, suf = 0; 
			pre = t[y].premx & 1 ? t[y].premx / 2 + 1 : t[y].premx / 2;
			suf = abs(t[y].sufmi) & 1 ? abs(t[y].sufmi) / 2 + 1 : abs(t[y].sufmi) / 2;
			printf("%d\n", pre + suf);
			root = merge(merge(x, y), z);
		}
		// dfs(root); puts("");
	}
	return 0;
}
2021/5/28 15:50
加载中...