AtCoder Beginner Contest 223 F - Parenthesis Checking(线段树)

Parenthesis Checking

题目大意:

给出一个括号串,q 次以下两种操作:

  1. 输入 1 l r,交换第 l-th 和 r-th 的字符
  2. 输出 2 l r ,查询区间 [l,r] 子串是否是合法括号序列。
思路:

(1)1

一个括号序列是否合法,关键在于判断序列是否前缀和为 0 且前缀和最小值为 0。

考虑使用线段树来维护区间和与前缀和最小值的信息。

Copy
struct Node { int sum; int minn; // 前缀和的最小值 Node(int x = 0) : sum(x), minn(x) {} Node operator+(const Node &node) const { Node res; res.minn = min(minn, sum + node.minn); res.sum = sum + node.sum; return res; } bool operator()() const { return sum == 0 && minn == 0; } };

区间和不必多说。

考虑前缀和的最小值,要么是左子节点前缀和的最小值,要么是左节点的区间和 + 右子节点前缀和的最小值,两者取 min。

Code:
Copy
#define ls (v << 1) #define rs (ls | 1) #define tm ((tl + tr) >> 1) struct Segment { int n; vector<Node> nodes; Segment(string &s) : n((int)s.length()), nodes(n << 2) { function<void(int, int, int)> dfs = [&](int v, int tl, int tr) { // 节点标号,维护的区间 if (tl == tr) { nodes[v] = Node(s[tm - 1] == '(' ? 1 : -1); } else { dfs(ls, tl, tm); dfs(rs, tm + 1, tr); nodes[v] = nodes[ls] + nodes[rs]; } }; dfs(1, 1, n); } void upd(int x, int y) { function<void(int, int, int)> dfs = [&](int v, int tl, int tr) { if (tl == tr) { nodes[v] = Node(y); } else { if (x <= tm) dfs(ls, tl, tm); else dfs(rs, tm + 1, tr); nodes[v] = nodes[ls] + nodes[rs]; } }; dfs(1, 1, n); } bool query(int x, int y) { function<Node(int, int, int)> dfs = [&](int v, int tl, int tr) { if (x <= tl && tr <= y) return nodes[v]; if (y <= tm) return dfs(ls, tl, tm); if (x > tm) return dfs(rs, tm + 1, tr); return dfs(ls, tl, tm) + dfs(rs, tm + 1, tr); }; return dfs(1, 1, n)(); } }; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n, q; cin >> n >> q; string s; cin >> s; Segment seg(s); while (q--) { int op, l, r; cin >> op >> l >> r; if (op == 1) { if (s[l - 1] != s[r - 1]) { int tmp = s[r - 1] == '(' ? 1 : -1; seg.upd(l, tmp); seg.upd(r, -tmp); swap(s[l - 1], s[r - 1]); } } else { cout << (seg.query(l, r) ? "Yes" : "No") << "\n"; } } return 0; }
posted @   Nepenthe8  阅读(67)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示