[ABC223F] Parenthesis Checking 题解
1.AT_abc333_e [ABC333E] Takahashi Quest 题解2.[ABC265F] Manhattan Cafe 题解3.[ABC271E] Subsequence Path 题解4.[ABC273D] LRUD Instructions 题解5.P8085 [COCI2011-2012#4] KRIPTOGRAM 题解6.[ABC238F] Two Exams 题解7.[ABC217F] Make Pair 题解8.[ABC219F] Cleaning Robot 题解9.[ABC219E] Moat 题解10.[ABC221D] Online games 题解11.[ABC221E] LEQ 题解12.[ABC223E] Placing Rectangles 题解13.[ABC211D] Number of Shortest paths 题解14.[ABC211F] Rectilinear Polygons 题解
15.[ABC223F] Parenthesis Checking 题解
16.CF154C Double Profiles 题解17.[ABC208D] Shortest Path Queries 2 题解18.[ABC212E] Safety Journey 题解19.[ABC229E] Graph Destruction 题解20.[ABC240E] Ranges on Tree 题解21.[ABC261E] Many Operations 题解22.P10842 【MX-J2-T3】Piggy and Trees 题解[ABC223F] Parenthesis Checking 题解
思路解析
在开始之前,首先我们需要知道合法括号序列的判断方法。我们可以给每个括号打上权值,设左括号权值为
现在我们已经知道了如何通过序列的前缀和数组判断该序列是否合法,接下来我们就考虑如何修改。我们可以先把前缀和数组存下来,然后考虑每一次交换会对这个数组产生怎样的影响。首先,若交换
- 若
位上的括号交换前是左括号时,可见由于第 位从 改成了 ,所以就会对该区间加上 的权值。 - 若
位上的括号交换前是右括号时,可见由于第 位从 改成了 ,所以就会对该区间加上 的权值。
最后考虑如何实现,我们需要做到区间求最小值,单点查询,区间加三种操作,可以想到使用线段树维护。注意由于我们存的值是前缀和,所以需要减去
code
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10, M = 8e5 + 10;
string str;
int n, q, a[N], s[M], t[M];
void push_up(int p) {
int ls = (p << 1), rs = (p << 1) + 1;
s[p] = min(s[ls], s[rs]);
}
void build(int p, int l, int r) {
if(l == r) {
s[p] = a[l];
return;
}
int m = l + ((r - l) >> 1), ls = (p << 1), rs = (p << 1) + 1;
build(ls, l, m);
build(rs, m + 1, r);
push_up(p);
}
void addt(int p, int l, int r, int k) {
s[p] += k;
t[p] += k;
}
void push_down(int p, int l, int r) {
if(!t[p]) return;
int m = l + ((r - l) >> 1), ls = (p << 1), rs = (p << 1) + 1;
addt(ls, l, m, t[p]);
addt(rs, m + 1, r, t[p]);
t[p] = 0;
}
void add(int p, int l, int r, int x, int y, int k) {
if(r < x || l > y) return;
if(l >= x && r <= y) {
addt(p, l, r, k);
return;
}
push_down(p, l, r);
int m = l + ((r - l) >> 1), ls = (p << 1), rs = (p << 1) + 1;
add(ls, l, m, x, y, k);
add(rs, m + 1, r, x, y, k);
push_up(p);
}
int ask(int p, int l, int r, int x, int y) {
if(r < x || l > y) return 2e9;
if(l >= x && r <= y) return s[p];
push_down(p, l, r);
int m = l + ((r - l) >> 1), ls = (p << 1), rs = (p << 1) + 1;
return min(ask(ls, l, m, x, y), ask(rs, m + 1, r, x, y));
}
int main() {
cin >> n >> q;
cin >> str;
str = ' ' + str;
for(int i = 1; i <= n; i++) {
a[i] = a[i - 1];
if(str[i] == '(') a[i]++;
else a[i]--;
}
build(1, 1, n);
while(q--) {
int op, l, r;
cin >> op >> l >> r;
if(op == 1) {
if(str[l] != str[r]) {
if(str[l] == '(') add(1, 1, n, l, r - 1, -2);
else add(1, 1, n, l, r - 1, 2);
swap(str[l], str[r]);
}
}
else {
int tmp = ask(1, 1, n, l - 1, l - 1);
if(l == 1) tmp = 0;
int t1 = ask(1, 1, n, l, r - 1) - tmp, t2 = ask(1, 1, n, r, r) - tmp;
if(t1 >= 0 && t2 == 0) cout << "Yes\n";
else cout << "No\n";
}
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探