AtCoder F - Parenthesis Checking

原题链接:AtCoder F - Parenthesis Checking

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

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

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

我们让(1,让)1,那么这样括号序列就成了只有11的一个序列,然后我们用线段树维护一个区间和,那么一个合法括号序列的条件就是这段区间和等于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 @   Xxaj5  阅读(58)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示