P10513 括号

Sol

某个题的加强版。

先考虑没有修改操作的,直接维护未匹配的左右括号,合并时直接匹配。

当有区间翻转操作时,直接维护反转和未反转的状态,反转时直接交换。

Code

#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define eb emplace_back
#define pf push_front
#define desktop "C:\\Users\\MPC\\Desktop\\"
#define IOS ios :: sync_with_stdio (false),cin.tie (0),cout.tie (0)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair <int,int> PII;
const int dx[] = {1,0,-1,0},dy[] = {0,-1,0,1};
template <typename T1,typename T2> bool tomax (T1 &x,T2 y) {
	if (y > x) return x = y,true;
	return false;
}
template <typename T1,typename T2> bool tomin (T1 &x,T2 y) {
	if (y < x) return x = y,true;
	return false;
}
LL power (LL a,LL b,LL p) {
	LL ans = 1;
	while (b) {
		if (b & 1) ans = ans * a % p;
		a = a * a % p;
		b >>= 1;
	}
	return ans;
}
int fastio = (IOS,0);
#define endl '\n'
#define puts(s) cout << (s) << endl
const int N = 1000010;
int n,m;
char s[N];
struct info {int lcnt,rcnt,ans;};
info operator + (info a,info b) {
	info ans;
	int t = min (a.rcnt,b.lcnt);
	ans.ans = a.ans + t + b.ans;
	ans.lcnt = a.lcnt + b.lcnt - t;
	ans.rcnt = a.rcnt + b.rcnt - t;
	return ans;
}
struct node {
	int l,r;
	info ans0,ans1;
	bool rev;
}tr[4 * N];
void push_up (node &rt,node l,node r) {
	rt.ans0 = l.ans0 + r.ans0;
	rt.ans1 = l.ans1 + r.ans1;
}
void push_up (int u) {
	push_up (tr[u],tr[u << 1],tr[u << 1 | 1]);
}
void opt_rev (int u) {
	swap (tr[u].ans0,tr[u].ans1);
	tr[u].rev ^= 1;
}
void push_down (int u) {
	if (tr[u].rev) {
		opt_rev (u << 1),opt_rev (u << 1 | 1);
		tr[u].rev = 0;
	}
}
void build (int u,int l,int r) {
	tr[u] = {l,r,{s[l] == ')',s[l] == '(',0},{s[l] == '(',s[l] == ')',0},0};
	if (l == r) return ;
	int mid = l + r >> 1;
	build (u << 1,l,mid),build (u << 1 | 1,mid + 1,r);
	push_up (u);
}
void modify (int u,int l,int r) {
	if (l <= tr[u].l && tr[u].r <= r) {
		opt_rev (u);
		return ;
	}
	push_down (u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) modify (u << 1,l,r);
	if (r >= mid + 1) modify (u << 1 | 1,l,r);
	push_up (u);
}
node query (int u,int l,int r) {
	if (l <= tr[u].l && tr[u].r <= r) return tr[u];
	push_down (u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (r <= mid) return query (u << 1,l,r);
	if (l >= mid + 1) return query (u << 1 | 1,l,r);
	node ans;
	push_up (ans,query (u << 1,l,r),query (u << 1 | 1,l,r));
	return ans;
}
int main () {
	cin >> n >> s + 1;
	build (1,1,n);
	cin >> m;
	while (m--) {
		int op,l,r;
		cin >> op >> l >> r;
		if (op == 1) modify (1,l,r);
		else {
			node ans = query (1,l,r);
			cout << ans.ans0.ans << endl;
		}
	}
	return 0;
}
posted @ 2025-05-17 19:46  incra  阅读(28)  评论(0)    收藏  举报