Description

给定一个长度为 \(n\) 的小括号序列,求有多少个位置满足将这个位置的括号方向反过来后使得新序列是一个合法的括号序列。即在任意一个位置前缀左括号的个数不少于前缀右括号的个数,同时整个序列左右括号个数相同

Input

第一行是一个整数 \(n\) 代表序列长度

下面一行是括号序列

Output

输出一行一个数字代表的答案

Hint

\(1~\leq~n~\leq~10^6\)

Solution

考虑一个位置,如果是左括号,那么能将其变成右括号当且仅当:

整个序列左括号个数比右括号多 \(2\)

在这个位置之前,所有位置的前缀左括号个数都不少于前缀右括号个数

在这个位置和这个位置之后,在修改后所有位置的前缀左括号个数都不少于前缀右括号个数

我们将第三条转化一下,由于在修改之后左括号个数减一,右括号个数加一,于是我们可以将第三条改为

在这个位置和这个位置之后,修改前所有位置的前缀左括号个数都比前缀右括号个数至少多两个

这样一个位置能不能修改就仅与原序列有关了。

若果是右括号,也同理进行分析,将两个改为 \(-2\) 个即可。

于是我们处理一下前缀左括号个数-右括号个数。

考虑第二条限制,等价于 \([1,pos]\) 这些前缀中的最小值不小于 \(0\)。于是我们对这些前缀求一个前缀最小值,就可以做到 \(O(1)\) 判断了。

对于第三条限制,等价于 \([pos,n]\) 这些前缀中的最小值不小于 \(2\)。于是我们对这些前缀求一个后缀最小值,也可以做到 \(O(1)\) 判断了。

这个位置是右括号的情况同理。细节参考代码

Code

#include <cstdio>
#include <algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif
#define rg register
#define ci const int
#define cl const long long typedef long long int ll; namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
} template <typename T>
inline void qr(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
} template <typename T>
inline void ReadDb(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
if (ch == '.') {
ch = IPT::GetChar();
double base = 1;
while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
}
if (lst == '-') x = -x;
} namespace OPT {
char buf[120];
} template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
rg int top=0;
do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
} const int maxn = 1000010; int n, ans;
int cnt[maxn], pre[maxn], post[maxn];
char MU[maxn]; int main() {
freopen("1.in", "r", stdin);
qr(n);
for (rg int i = 1; i <= n; ++i) {
do {MU[i] = IPT::GetChar();} while ((MU[i] != '(') && (MU[i] != ')'));
if (MU[i] == '(') cnt[i] = cnt[i - 1] + 1;
else cnt[i] = cnt[i - 1] - 1;
}
if ((cnt[n] != 2) && (cnt[n] != -2)) return puts("0") & 1;
pre[0] = maxn; post[n + 1] = maxn;
for (rg int i = 1; i <= n; ++i) pre[i] = std::min(pre[i - 1], cnt[i]);
for (rg int i = n; i; --i) post[i] = std::min(post[i + 1], cnt[i]);
for (rg int i = 1; i <= n; ++i) {
if (MU[i] == '(') {
if ((cnt[n] == 2) && (post[i] >= 2) && (pre[i - 1] >= 0)) ++ans;
} else {
if ((cnt[n] == -2) && (post[i] >= -2) && (pre[i - 1] >= 0)) ++ans;
}
}
qw(ans, '\n', true);
return 0;
}

【乱搞】【CF1095E】 Almost Regular Bracket Sequence的更多相关文章

  1. CF1095E Almost Regular Bracket Sequence

    题目地址:CF1095E Almost Regular Bracket Sequence 真的是尬,Div.3都没AK,难受QWQ 就死在这道水题上(水题都切不了,我太菜了) 看了题解,发现题解有错, ...

  2. E. Almost Regular Bracket Sequence 解析(思維)

    Codeforce 1095 E. Almost Regular Bracket Sequence 解析(思維) 今天我們來看看CF1095E 題目連結 題目 給你一個括號序列,求有幾個字元改括號方向 ...

  3. Educational Codeforces Round 4 C. Replace To Make Regular Bracket Sequence 栈

    C. Replace To Make Regular Bracket Sequence 题目连接: http://www.codeforces.com/contest/612/problem/C De ...

  4. Codeforces Beta Round #5 C. Longest Regular Bracket Sequence 栈/dp

    C. Longest Regular Bracket Sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.c ...

  5. Replace To Make Regular Bracket Sequence

    Replace To Make Regular Bracket Sequence You are given string s consists of opening and closing brac ...

  6. D - Replace To Make Regular Bracket Sequence

    You are given string s consists of opening and closing brackets of four kinds <>, {}, [], (). ...

  7. CodeForces - 612C Replace To Make Regular Bracket Sequence 压栈

    C. Replace To Make Regular Bracket Sequence time limit per test 1 second memory limit per test 256 m ...

  8. (CodeForces - 5C)Longest Regular Bracket Sequence(dp+栈)(最长连续括号模板)

    (CodeForces - 5C)Longest Regular Bracket Sequence time limit per test:2 seconds memory limit per tes ...

  9. 贪心+stack Codeforces Beta Round #5 C. Longest Regular Bracket Sequence

    题目传送门 /* 题意:求最长括号匹配的长度和它的个数 贪心+stack:用栈存放最近的左括号的位置,若是有右括号匹配,则记录它们的长度,更新最大值,可以在O (n)解决 详细解释:http://bl ...

  10. Almost Regular Bracket Sequence CodeForces - 1095E (线段树,单点更新,区间查询维护括号序列)

    Almost Regular Bracket Sequence CodeForces - 1095E You are given a bracket sequence ss consisting of ...

随机推荐

  1. 用Python爬下今日头条所有美女,美滋滋!

      我们的学习爬虫的动力是什么? 有人可能会说:如果我学好了,我可以找一个高薪的工作. 有人可能会说:我学习编程希望能够为社会做贡献(手动滑稽) 有人可能会说:为了妹子! ..... 其实我们会发现妹 ...

  2. Java微笔记(9)

    使用 Date 和 SimpleDateFormat 类表示时间 处理日期和时间的相关数据,可以使用 java.util 包中的 Date 类 使用 Date 类的默认无参构造方法创建出的对象就代表当 ...

  3. fastjson&gson

    1.model转fastjson时,model成员变量是对象的,再转成fastjson时,不能仅仅判断key是否存在.应该判断其值是否为"". 2.gson 在 dao层貌似没有用 ...

  4. sleep(),wait(),yield(),notify()

    sleep(),wait(),yield() 的区别 sleep方法和yield方法是Thread类的方法,wait方法是Object的方法. sleep 方法使当前运行中的线程睡眼一段时间,进入不可 ...

  5. 操作系统作业一——仿CMD

    实验一.CMD实验 2014商软2  卓宇靖  4238 一.        实验目的 (1)掌握命令解释程序的原理: (2)掌握简单的DOS调用方法: (3)掌握C语言编程初步. 二.        ...

  6. java复利计算基本代码

    源代码: public class Calculate { public static void main(String[] args){ double money = 1000; //本金 int ...

  7. 明白JavaScript原型链和JavaScrip继承

    原型链是JavaScript的基础性内容之一.其本质是JavaScript内部的设计逻辑. 首先看一组代码: <script type="text/javascript"&g ...

  8. jdbc 小结

    1,PreparedStatement/Statement区别: 1,防止sql注入式攻击(sql注入:就是通过非正常手段(比如在url中添加参数)),将sql文执行(比如or 1=1) 2,Prep ...

  9. node web 应用热更新

    在每次更改完 node.js 项目后,我们都需要先将 node.js停止(快捷键: Ctrl+C),然后再通过命令再次运行,这样特别麻烦.这里我推荐使用 supervisor工具, npm 安装命令为 ...

  10. 【bzoj2257】[Jsoi2009]瓶子和燃料 扩展裴蜀定理+STL-map

    题目描述 给出 $n$ 个瓶子和无限的水,每个瓶子有一定的容量.每次你可以将一个瓶子装满水,或将A瓶子内的水倒入B瓶子中直到A倒空或B倒满.从中选出 $k$ 个瓶子,使得能够通过这 $k$ 个瓶子凑出 ...