Sereja and Brackets CodeForces - 380C (树状数组+离线)
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 l**i, r**i(1 ≤ l**i ≤ r**i ≤ 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 l**i, r**i (1 ≤ l**i ≤ r**i ≤ 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 = s**k1s**k2... 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,代表一个区间。对于每一个询问,让你输出区间中能选出最长的子序列是合法的括号序列的长度。
思路:
对询问区间进行离线保存,以右端点升序来排序,
然后从坐向右扫描,用stack来维护每一个还没被匹配到的(字符的下标,
当来一个)字符的时候,将其和栈顶的那个(匹配,同时用树状数组在(的下标的数值上+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 id;
} a[maxn];
char s[maxn];
int n;
int m;
bool cmp(node aa, node bb)
{
return aa.r < bb.r;
}
int tree[maxn];
int lowbit(int x)
{
return x & (-1 * x);
}
void add(int x, int val)
{
while (x <= n) {
tree[x] += val;
x += lowbit(x);
}
}
int ask(int x)
{
int res = 0;
while (x) {
res += tree[x];
x -= lowbit(x);
}
return res;
}
int ans[maxn];
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
gbtb;
cin >> s + 1;
n=strlen(s+1);
cin >> m;
repd(i, 1, m ) {
cin >> a[i].l >> a[i].r;
a[i].id = i;
}
sort(a + 1, a + 1 + m, cmp);
stack<int> st;
while (sz(st)) {
st.pop();
}
int pos = 1;
repd(i, 1, m) {
// chu(pos);
repd(j, pos, a[i].r) {
if (s[j] == '(') {
st.push(j);
} else {
if (sz(st)) {
add(st.top(), 2);
st.pop();
}
}
}
ans[a[i].id] = ask(a[i].r) - ask(a[i].l - 1);
pos = a[i].r + 1;
}
repd(i,1,m)
{
printf("%d\n",ans[i] );
}
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';
}
}
}
Sereja and Brackets CodeForces - 380C (树状数组+离线)的更多相关文章
- CodeForces 380C Sereja and Brackets(扫描线+树状数组)
[题目链接] http://codeforces.com/problemset/problem/380/C [题目大意] 给出一个括号序列,求区间内左右括号匹配的个数. [题解] 我们发现对于每个右括 ...
- 2016 Multi-University Training Contest 5 1012 World is Exploding 树状数组+离线化
http://acm.hdu.edu.cn/showproblem.php?pid=5792 1012 World is Exploding 题意:选四个数,满足a<b and A[a]< ...
- SPOJ DQUERY树状数组离线or主席树
D-query Time Limit: 227MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submit Status ...
- D-query SPOJ 树状数组+离线
D-query SPOJ 树状数组+离线/莫队算法 题意 有一串正数,求一定区间中有多少个不同的数 解题思路--树状数组 说明一下,树状数组开始全部是零. 首先,我们存下所有需要查询的区间,然后根据右 ...
- Necklace HDU - 3874 (线段树/树状数组 + 离线处理)
Necklace HDU - 3874 Mery has a beautiful necklace. The necklace is made up of N magic balls. Each b ...
- HDU 3333 | Codeforces 703D 树状数组、离散化
HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...
- codeforces 341d (树状数组)
problem Iahub and Xors 题目大意 一个n*n的矩阵,要求支持两种操作. 操作1:将一个子矩阵的所有值异或某个数. 操作2:询问某个子矩阵的所以值的异或和. 解题分析 由于异或的特 ...
- Codeforces Round #365 (Div. 2) D 树状数组+离线处理
D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes in ...
- CodeForces 396C 树状数组 + DFS
本主题开始看到以为段树或树状数组,但是,对于一个节点的有疑问的所有子节点的加权,这一条件被视为树的根,像 然后1号是肯定在第一层中,然后建立一个单向侧倒查,然后记录下来 其中每个节点 层,终于 两个节 ...
随机推荐
- Java 基础篇之lambda
Lambda 示例 public interface Eatable { void taste(); } public interface Flyable { void fly(String weat ...
- 支付宝网站即时支付开发,MD5加签名规则处理代码展示
一.如果传入进来的Object对象,最后生成制定格式的字符换 text: list拼接成字符串,map中的所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,list的元素之间用“| ...
- Mac 操作小技巧
系统版本 MacOs Mojava # 快捷键篇: 1. 打开终端:command+空格,输入terminal:在终端页面,新建终端command + T 2. 打开文件夹:command + T 3 ...
- 第三次Java实验报告
Java实验报告 班级 计科二班 学号20188437 姓名 何磊 完成时间 2019/9/22 评分等级 实验三 String类的应用 实验目的 掌握类String类的使用: 学会使用JDK帮助文档 ...
- Oracle创建表空间、创建用户,给用户分配表空间以及可操作权限
创建表空间一共可分为四个步骤 具体脚本如下: 第1步:创建临时表空间 create temporary tablespace yd_temp tempfile 'D:\oracledata ...
- soap-ws获取ws中的所有的接口方法
soap-ws获取wsdl中的所有的接口方法 示例wsdl文件如下,生成的过程可以参考https://www.cnblogs.com/chenyun-/p/11502446.html: <def ...
- VIM 介绍
gedit a.txt 是一个图形界面的文本编辑器. 需要安装图形界面才会有. nano a.txt 也是一样的 vi 是一种文本界面的编辑器. vim 是 vimsual interfa ...
- Linux系列(7):入门之磁盘与文件系统管理
1.磁盘的主要概念 下面展示一下磁盘结构图: 1.磁道 2.柱面 3.物理扇区 已经了解了这么多概念,现在总结一下 4.磁盘分区 1.概念 磁盘分区就是将磁盘划分成不同的区域. 2.分区的最小单位 早 ...
- matplotlib库绘制散点图
假设通过爬虫你获取到了北京2016年3,10月份每天白天的最高气温(分别位于列表a,b),那么此时如何寻找出气温随时间(天)变化的某种规律? a = [11,17,16,11,12,11,12,6,6 ...
- DRF cbv源码分析 restful规范10条 drf:APIView的源码 Request的源码 postman的安装和使用
CBV 执行流程 路由配置:url(r'^test/',views.Test.as_view()), --> 根据路由匹配,一旦成功,会执行后面函数(request) --> 本质就是执 ...