zoukankan      html  css  js  c++  java
  • AtCoder F

    原题链接: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;
    }
    
  • 相关阅读:
    卷积神经网络(Convolutional Neural Network,CNN)
    理解滑动平均(exponential moving average)
    python2到python3代码转化:2to3
    Mac查看和杀死后台进程
    pip安装python库时使用国内镜像资源加速下载过程
    关于pip安装时提示"pkg_resources.DistributionNotFound"错误
    【Linux基础】压缩和解压
    【Linux基础】常用Linux命令: cd, cp, ls, mkdir, mv, rm, su, uname
    【python3基础】相对路径,‘/’,‘./’,‘../’
    剑指offer-学习笔记
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/15451884.html
Copyright © 2011-2022 走看看