Sereja and Brackets

题目链接: CodeForces - 380C

Sereja has a bracket sequence s1, s2, ..., *s**n, or, in other words, a string s* of length n, consisting of characters "(" and ")".

Sereja needs to answer m queries, each of them is described by two integers li, ri(1 ≤ li ≤ ri ≤ n). The answer to the i-th query is the length of the maximum correct bracket subsequence of sequence sli, sli + 1, ..., sri. Help Sereja answer all queries.

You can find the definitions for a subsequence and a correct bracket sequence in the notes.

Input

The first line contains a sequence of characters s1, s2, ..., *s**n* (1 ≤ n ≤ 106) without any spaces. Each character is either a "(" or a ")". The second line contains integer m (1 ≤ m ≤ 105) — the number of queries. Each of the next m lines contains a pair of integers. The i-th line contains integers li, ri (1 ≤ li ≤ ri ≤ n) — the description of the i-th query.

Output

Print the answer to each question on a single line. Print the answers in the order they go in the input.

Examples

Input

())(())(())(71 12 31 21 128 125 112 10

Output

00210466

Note

A subsequence of length |x| of string s = s1s2... s|s| (where |s| is the length of string s) is string x = sk1sk2... *s**k|x| (1 ≤ k1 < k2 < ... < k|x| ≤ |s*|).

A correct bracket sequence is a bracket sequence that can be transformed into a correct aryphmetic expression by inserting characters "1" and "+" between the characters of the string. For example, bracket sequences "()()", "(())" are correct (the resulting expressions "(1)+(1)", "((1+1)+1)"), and ")(" and "(" are not.

For the third query required sequence will be «()».

For the fourth query required sequence will be «()(())(())».

题意:

给你一个只含有'(' 和')' 的字符串,

以及q个询问,每一个询问给你两个整数l和r,代表一个区间。对于每一个询问,让你输出区间中能选出最长的子序列是合法的括号序列的长度。

思路:

线段树+分治的思想来解决此问题。

我们线段树每一个区间维护以下信息:

1、区间中能选出最长的子序列是合法的括号序列的个数 num。

2、 区间中多余的'(' 字符的个数 a

3、区间中多余的')' 字符的个数 b

那么对于区间合并时,

num=左儿子的num+右儿子的num+min(左儿子的a,右儿子的b)

a=左儿子的a+右儿子的a - min(左儿子的a,右儿子的b)

b=左儿子的b+右儿子的b - min(左儿子的a,右儿子的b)

最后输出时,注意num个括号个数,*2才是长度。

细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 1000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
struct node {int l, r;int num;int a;// (int b;// )
} segmeng_tree[maxn << 2];
char s[maxn];
int n;
int m;
void pushup(int rt)
{int x = min(segmeng_tree[rt << 1].a, segmeng_tree[rt << 1 | 1].b);segmeng_tree[rt].num = x + segmeng_tree[rt << 1].num + segmeng_tree[rt << 1 | 1].num;segmeng_tree[rt].a = segmeng_tree[rt << 1].a + segmeng_tree[rt << 1 | 1].a - x;segmeng_tree[rt].b = segmeng_tree[rt << 1].b + segmeng_tree[rt << 1 | 1].b - x;
}
void build(int rt, int l, int r)
{segmeng_tree[rt].l = l;segmeng_tree[rt].r = r;if (l == r) {segmeng_tree[rt].a = s[l] == '(';segmeng_tree[rt].b = s[l] == ')';segmeng_tree[rt].num = 0;} else {int mid = (l + r) >> 1;build(rt << 1, l, mid);build(rt << 1 | 1, mid + 1, r);pushup(rt);}
}node ask(int rt, int l, int r)
{if (segmeng_tree[rt].l >= l && segmeng_tree[rt].r <= r) {return segmeng_tree[rt];}int mid = (segmeng_tree[rt].l + segmeng_tree[rt].r) >> 1;if (r <= mid) {return ask(rt << 1, l, r);} else if (l > mid) {return ask(rt << 1 | 1, l, r);} else {node res1 = ask(rt << 1, l, r);node res2 = ask(rt << 1 | 1, l, r);node res = res1;int x = min(res1.a, res2.b);res.num += x;res.b += res2.b;res.a += res2.a;res.num += res2.num;res.b -= x;res.a -= x;return res;}
}
int main()
{//freopen("D:\\code\\text\\input.txt","r",stdin);//freopen("D:\\code\\text\\output.txt","w",stdout);scanf("%s", s + 1);n = strlen(s + 1);build(1, 1, n);scanf("%d", &m);while (m--) {int l, r;scanf("%d %d", &l, &r);printf("%d\n", ask(1, l, r).num * 2);}return 0;
}inline void getInt(int *p)
{char ch;do {ch = getchar();} while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '0');while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 - ch + '0';}} else {*p = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 + ch - '0';}}
}

转载于:https://www.cnblogs.com/qieqiemin/p/11491557.html

Sereja and Brackets CodeForces - 380C (线段树+分治思路)相关推荐

  1. Sereja and Brackets CodeForces - 380C (树状数组+离线)

    Sereja and Brackets 题目链接: CodeForces - 380C Sereja has a bracket sequence s1, s2, ..., *s**n, or, in ...

  2. Codeforces 1140F 线段树 分治 并查集

    题意及思路:https://blog.csdn.net/u013534123/article/details/89010251 之前cf有一个和这个相似的题,不过那个题只有合并操作,没有删除操作,直接 ...

  3. CodeForces - 1217F Forced Online Queries Problem(线段树分治+并查集撤销)

    题目链接:点击查看 题目大意:给出 nnn 个点,初始时互相不存在连边,需要执行 mmm 次操作,每次操作分为两种类型: 1xy1 \ x \ y1 x y:如果 (x,y)(x,y)(x,y) 之间 ...

  4. 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

    不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...

  5. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

  6. 线段树分治 ---- F. Extending Set of Points(线段树分治 + 可撤销并查集)

    题目链接 题目大意: 你有个点集合SSS,每次往集合里面加点或者删点(如果要加的点出现过),如果(x1,y1),(x2,y1),(x1,y2),(x2,y2)(x1,y1),(x2,y1),(x1,y ...

  7. 线段树分治 ---- CF1217F - Forced Online Queries Problem(假离线 可撤销并查集 + 线段树分治)详解

    题目链接 题目大意 解题思路: 我一开始想到可以用可撤销并查集去维护这种删边加边的操作,但是有个缺点是每次撤销都有把后面的边全部撤销复度是O(n2)O(n^2)O(n2) 首先我们考虑这种动态加边删边 ...

  8. 3237: [Ahoi2013]连通图 线段树分治

    题解: cf765f cf671e bzoj4184 bzoj4552 线段树分治裸题 还是介绍一下线段树分治 这个东西其实挺简单但也挺有用的 可以把删除+插入操作变成只有插入(倒着就是删除) 像这一 ...

  9. LOJ 121 「离线可过」动态图连通性——LCT维护删除时间最大生成树 / 线段树分治...

    题目:https://loj.ac/problem/121 离线,LCT维护删除时间最大生成树即可.注意没有被删的边的删除时间是 m+1 . 回收删掉的边的节点的话,空间就可以只开 n*2 了. #i ...

最新文章

  1. 帝国理工学院(IC)研究人员设计了一种可以解决瘫痪的脑机设备
  2. [LeetCode226]Invert Binary Tree
  3. 【Python】20个Pandas数据实战案例,干货多多
  4. vue2实践揭秘pdf_《Vue2实践揭秘》源码
  5. Web服务生存周期内发生的事件/Soap扩展的阶段/Soap扩展的步骤
  6. C语言存储地址规律,一数组按顺序序存放,插入一个数,按原来排序规律放在相应位置...
  7. 如何正确添加水印保护自己的版权?
  8. 毕设-基于SSM高校后勤管理系统
  9. PR菜鸟入门 -- PR下载安装
  10. 楠哥Java SE总结详细笔记
  11. 使用FOP将xml转换pdf
  12. 不经历风雨,怎么见彩虹,没有人能随随便便成功
  13. 语法分析--自上而下分析的基本问题
  14. Qt OpenGL 旋转、平移、缩放
  15. NOI2014魔法森林--LCT
  16. “懂行人”加码远程医疗建设,陕西省人民医院用科技打破时空限制
  17. 陕西谷县数百万斤红枣滞销贱卖喂牛-红枣滞销-农产品销路-贱卖
  18. 使用itext为已有的pdf文档生成书签
  19. 使用Java合并多个word文档
  20. 【软考】电子商务的分类 - 中级电子商务设计师考点分析

热门文章

  1. Java AOP研究之How is beforeMethodAdvice called
  2. 如何处理SAP OData错误消息: Invalid parametertype used at function XXXX
  3. nodejs连接redis,redis服务器的地址格式应该怎么写
  4. 采访问题 What is your role at XX and what are your responsibilities
  5. 再论SAP云平台上CloudFoundry编程环境的connectivity
  6. SAP成都研究院廖婧:SAP C4C社交媒体集成概述
  7. hive增量表和全量表_hive 拉链表 实现全量数据 增量更新
  8. python工程技巧_重点来了!掌握这些Python技巧,将给你节省大量时间
  9. shell 连接 mysql_如何把mysql语句写在shell里,运行后仍然是一个与mysql数据库连接的状态?...
  10. python exe文件运行依赖环境_python将py代码文件转换为EXE脱离环境运行