AtCoder F - Parenthesis Checking

原题链接:AtCoder F - Parenthesis Checking

一个全由\('('\)\(')'\)构成的字符串,由以下两个操作:

  • 1 l r交换字符串第\(l\)个和第\(r\)个字符。
  • 2 l r询问\(S[l-r]\)是否是一个合法序列。

很明显是一个线段树操作,这题蓝桥杯貌似有类似的,但是那道题貌似要用平衡树,也是操作之后判断括号序列是否合法,现在终于找到答案了,方法。

我们让\('('\)\(1\),让\(')'\)\(-1\),那么这样括号序列就成了只有\(1\)\(-1\)的一个序列,然后我们用线段树维护一个区间和,那么一个合法括号序列的条件就是这段区间和等于\(0\),然后这个区间的前缀和得大于\(0\)

区间和好维护,但是区间前缀和怎么维护,那我们就维护一个前缀最小值就\(ok\)了,对于\(pushup\),也就是\(min(左子树的最小值,左子树的和+右子树最小值)\),很巧妙,塞给队友队友直接秒了,然后我想了一天多。

#include <bits/stdc++.h>

using namespace std;

const int N = 2E5 + 10;
int W[N];

struct SegmentTree {
	int l, r;
	int sum, pre_min;
} tr[N * 4];

void push_up(int u) {
	tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
	tr[u].pre_min = min(tr[u << 1].pre_min, tr[u << 1].sum + tr[u << 1 | 1].pre_min);
}

void build(int u, int l, int r) {
	if (l == r) {
		tr[u] = { l, r, W[r], W[r] };
	}
	else {
		int mid = l + r >> 1;
		tr[u] = { l, r };
		build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
		push_up(u);
	}
}

void modify(int u, int x, int v) {
	if (tr[u].l == tr[u].r) {
		tr[u].sum = tr[u].pre_min = v;
	}
	else {
		int mid = tr[u].l + tr[u].r >> 1;
		if (x <= mid) modify(u << 1, x, v);
		else modify(u << 1 | 1, x, v);
		push_up(u);
	}
}

pair<int, int> query(int u, int l, int r) {
	if (l <= tr[u].l && tr[u].r <= r) {
		return { tr[u].sum, tr[u].pre_min };
	}
	else {
		int mid = tr[u].l + tr[u].r >> 1;
		pair<int, int> left = { 0, 0 };
		if (l <= mid) left = query(u << 1, l, r);
		pair<int, int> right = { 0, 0 };
		if (r > mid) right = query(u << 1 | 1, l, r);
		//auto right = query(u << 1 | 1, l, r);
		return { left.first + right.first, min(left.second, left.first + right.second) };
	}
}

int main() {
	int n, q;
	string s;
	cin >> n >> q;
	cin >> s;
	for (int i = 0; i < n; i++) W[i + 1] = (s[i] == '(' ? 1 : -1);
	build(1, 1, n);
	while (q--) {
		int op, l, r;
		cin >> op >> l >> r;
		if (op == 1) {
			swap(W[l], W[r]);
			modify(1, l, W[l]), modify(1, r, W[r]);
		}
		else {
			auto t = query(1, l, r);
			if (t.first == 0 && t.second >= 0) puts("Yes");
			else puts("No");
		}
	}

	return 0;
}
posted @ 2021-10-24 17:06  Xxaj5  阅读(53)  评论(0编辑  收藏  举报