CF380C. Sereja and Brackets[线段树 区间合并]
1 second
256 megabytes
standard input
standard output
Sereja has a bracket sequence s1, s2, ..., sn, 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.
The first line contains a sequence of characters s1, s2, ..., sn (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.
Print the answer to each question on a single line. Print the answers in the order they go in the input.
())(())(())(
7
1 1
2 3
1 2
1 12
8 12
5 11
2 10
0
0
2
10
4
6
6
A subsequence of length |x| of string s = s1s2... s|s| (where |s| is the length of string s) is string x = sk1sk2... sk|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 «()(())(())».
一定要读懂题
问的是匹配的括号子序列的最大长度
其实也就是最多有几对匹配*2
用线段树做
We will support the segments tree. At each vertex will be stored:
av — the maximum length of the bracket subsequence
bv — how many there it open brackets that sequence doesn't contain
cv — how many there it closed brackets that sequence doesn't contain
If we want to combine two vertices with parameters (a1, b1, c1) and (a2, b2, c2), we can use the following rules:
t = min(b1, c2)
a = a1 + a2 + t
b = b1 + b2 - t
c = c1 + c2 - t
读懂题就很明白了,就是个合并问题
查询的时候可以像GSS1那样写qpre和qsuf,但这次采用一个新方法,merge和query返回节点,这样方便好多
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define m ((l+r)>>1)
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define lc o<<1
#define rc o<<1|1
using namespace std;
typedef long long ll;
const int N=1e6+,INF=2e9+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
char s[N];
int q,ql,qr;
struct node{
int a,b,c;
node():a(),b(),c(){}
}t[N<<]; inline node merge(node x,node y){
node z;
int t=min(x.b,y.c);
z.a=x.a+y.a+t;
z.b=x.b+y.b-t;
z.c=x.c+y.c-t;
//printf("merge %d %d %d\n",z.a,z.b,z.c);
return z;
}
void build(int o,int l,int r){
if(l==r){
if(s[l]=='(') t[o].b=;
else t[o].c=;
}else{
build(lson);
build(rson);
t[o]=merge(t[lc],t[rc]);
}
}
node query(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return t[o];
else{
node ans;
if(ql<=m) ans=merge(ans,query(lson,ql,qr));
if(m<qr) ans=merge(ans,query(rson,ql,qr));
return ans;
}
}
int main(){
scanf("%s",s+);
q=read();
int n=strlen(s+);
build(,,n);
for(int i=;i<=q;i++){
ql=read();qr=read();
printf("%d\n",query(,,n,ql,qr).a*);
}
}
CF380C. Sereja and Brackets[线段树 区间合并]的更多相关文章
- Codeforces Round #223 (Div. 2) E. Sereja and Brackets 线段树区间合并
题目链接:http://codeforces.com/contest/381/problem/E E. Sereja and Brackets time limit per test 1 secon ...
- POJ 3667 Hotel(线段树 区间合并)
Hotel 转载自:http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html [题目链接]Hotel [题目类型]线段树 ...
- HDU 3911 线段树区间合并、异或取反操作
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3911 线段树区间合并的题目,解释一下代码中声明数组的作用: m1是区间内连续1的最长长度,m0是区间内连续 ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- HYSBZ 1858 线段树 区间合并
//Accepted 14560 KB 1532 ms //线段树 区间合并 /* 0 a b 把[a, b]区间内的所有数全变成0 1 a b 把[a, b]区间内的所有数全变成1 2 a b 把[ ...
- poj3667 线段树 区间合并
//Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- hdu3911 线段树 区间合并
//Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- 线段树(区间合并) POJ 3667 Hotel
题目传送门 /* 题意:输入 1 a:询问是不是有连续长度为a的空房间,有的话住进最左边 输入 2 a b:将[a,a+b-1]的房间清空 线段树(区间合并):lsum[]统计从左端点起最长连续空房间 ...
- HDU 3308 LCIS (线段树区间合并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308 题目很好懂,就是单点更新,然后求区间的最长上升子序列. 线段树区间合并问题,注意合并的条件是a[ ...
随机推荐
- csharp: .NET Object Relationional Mapper (ORM)- SubSonic
https://github.com/subsonic/SubSonic-3.0 http://subsonic.codeplex.com/ https://code.google.com/archi ...
- combox
通过combox控件本身的item添加了选项后,该控件在启动后SelectedIndex默认值是-1,所以最好是在窗体加载的时候初始化城SelectedIndex=0 另外如果是窗体加载时item从数 ...
- sqlserver2008存储过程(比较两个日期大小和获取当前月最大天数的存储过程)
下面简单介绍sqlserver2008两个常用的存储过程 1.比较两个日期大小的存储过程 2.获取当前月份的最大天数的存储过程 1.创建比较两个日期大小的存储过程 1)创建比较两个日期大小的存储过程 ...
- PHP 检测机器人,屏蔽内页
PHP 检测机器人,屏蔽内页 <?php // SpiderHelper::rewrite301(); // SpiderHelper::showRobotTxt(); class Spider ...
- [译]Godot系列教程三 - 场景实例化(续)
场景实例化(续) 要点 场景实例化带来很多便利的用法,总体来说有: 将场景细分,更便于管理 相对于某些引擎中的Prefab组件更灵活,并且在许多方面更强大 是一种设计更复杂的游戏流程甚至UI的方式 这 ...
- json-lib的使用《二》
上篇文章主要集中在了使用json-lib来实现JSON字符串和java中的对象的互转上,忽视了json-lib本身的功能,json-lib中有两个类比较重要:JSONObject和JSONArray, ...
- Struts,spring,hibernate三大框架的面试
Struts,spring,hibernate三大框架的面试 1.Hibernate工作原理及为什么要用? 原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3 ...
- 使用AngularJS实现简单:全选和取消全选功能
这里用到AngularJS四大特性之二----双向数据绑定 注意:没写一行DOM代码!这就是ng的优点,bootstrap.css为了布局,JS代码也只是简单创建ng模块和ng控制器 效果: < ...
- AlloyRenderingEngine开门大吉
快速入口 不读文章可以直接拐向这里: github:https://github.com/AlloyTeam/AlloyRenderingEngine website:http://alloyteam ...
- 码代码新神器-Github Atom
周末闲着没事,逛论坛发现了一个新的编辑器,由github发布的Atom编辑器.瞬间被吸引了,所以就去尝试着折腾了一下,后来发现这个编辑器确实很不错,他的特点就是两个字:优美!!! 下载地址,官方网站下 ...