CSU - 1542 Flipping Parentheses (线段树)
Posted zhchoutai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSU - 1542 Flipping Parentheses (线段树)相关的知识,希望对你有一定的参考价值。
CSU - 1542
Description Input
Output
Sample Input 6 3 ((())) 4 3 1 Sample Output 2 2 1 Hint
题意:先给出一个符合括号匹配的字符串。然后Q次操作 每次操作将某个括号反转,问将哪个括号反转能使字符串的括号再次匹配,位置要取最左端符合条件的。 能够利用前缀和 比方(())那么前缀和分别就是1,2,1,0。观察到。平衡时前缀和都是等于0的。
通过前缀和,我们能够发现规律: 将一个‘(‘翻转成‘)‘会使得从当前位置開始到字符串最后的前缀和都会减2 假设将‘)‘翻转成‘(‘,同理,此位置開始以后的全部前缀和都要加2 而假设减去了2,那怎样添加2抵消掉之前的影响,得到最后的后缀和为零 而减去2的话肯定是‘(‘翻转成‘)‘。那么怎样加一个数抵消掉‘)‘的影响 假设是将p点翻转的话,肯定是从[1,p],找一个‘)‘,将‘)‘翻转成‘(‘ 有没有发现规律,假设是‘(‘翻转成‘)‘,则是在之前的区间将‘)‘翻转成‘(‘。那么将‘)‘翻转成‘(‘时,就是往后,找一个‘(‘将其‘(‘翻转成‘)‘ 维护该区间的最小值就可以。仅仅要最小值不小于2,那么该区间的全部值都不会小于2 提供一个朋友的具体解释地址,说的非常好:http://blog.csdn.net/qwb492859377/article/details/47357553 /* Author: 2486 Memory: 32700 KB Time: 760 MS Language: C++ Result: Accepted VJ RunId: 4340427 Real RunId: 149963 */ #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; #define lson rt << 1, l, mid #define rson rt << 1|1, mid + 1, r #define root 1, 1, n const int MAXN = 5e5 + 5; const int INF = 0x3f3f3f3f; int sum[MAXN << 2]; int Min[MAXN << 2],col[MAXN << 2],val[MAXN << 2]; int S,n,m; char str[MAXN]; void pushup_1(int rt) { sum[rt] = min(sum[rt << 1], sum[rt << 1|1]); } void build(int rt, int l, int r) { col[rt] = 0; if(l == r) { val[rt] = (str[l] == ‘(‘ ? 1 : -1); S += val[rt]; Min[rt] = S; sum[rt] = val[rt] == 1 ? |
以上是关于CSU - 1542 Flipping Parentheses (线段树)的主要内容,如果未能解决你的问题,请参考以下文章
(Easy) Flipping an Image LeetCode