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号是肯定在第一层中,然后建立一个单向侧倒查,然后记录下来 其中每个节点 层,终于 两个节 ...
随机推荐
- 利用canvas对图片进行切割
使用input标签选择一张图片, 然后利用canvas对图片进行切割, 可以设置切割的行数和列数 这是html代码 ... <input type="file" id=&qu ...
- Java和SQL取两个字符间的值
Java String str = "abcdefg"; String result = str.substring(str.indexOf(">")+1 ...
- 【转】linux下nginx相关操作
参考文章 <nginx启动,重启,关闭命令> 停止操作 停止操作是通过向nginx进程发送信号(什么是信号请参阅linux文 章)来进行的 步骤1:查询nginx主进程号 ps -ef | ...
- mybatis 传递多个查询参数
方法1:顺序传参法 public User selectUser(String name, int deptId); <select id="selectUser" resu ...
- 【POJ - 3614】Sunscreen (优先队列)
Sunscreen Descriptions C (1 ≤ C ≤ 2500) 头奶牛在海滩边晒太阳,要避免在日光浴时产生难看的灼伤,每头奶牛必须用防晒霜覆盖它的皮肤.第 i 头奶牛有一个最小和最大 ...
- PYTHON 100days学习笔记006:函数和模块的使用
目录 Day006:函数和模块的使用 1.函数的作用 2.定义函数 2.1 语法 2.2 实例 2.3 函数的调用 4.函数的参数 4.1 必须参数 4.2 关键字参数 4.3 默认参数 4.4 不定 ...
- react项目开发环境搭建
1.环境安装,首先要安装node http://nodejs.cn/ 进入nodejs下载,你是window就下在window的反之,安装下一步下一步...就好了 安装成功了试试 node -v , ...
- 【LOJ】#3093. 「BJOI2019」光线
LOJ#3093. 「BJOI2019」光线 从下到上把两面镜子合成一个 新的镜子是\((\frac{a_{i}a_{i + 1}}{1 - b_{i}b_{i + 1}},b_{i} + \frac ...
- DOM、BOM
DOM DOM 是 W3C(万维网联盟)的标准. DOM 定义了访问 HTML 和 XML 文档的标准: “W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新 ...
- python 初始化__init__()
init()方法的重要性体现在两点. 1.初始化既是对象生命周期的开始,也是非常重要的一个步骤,每个对象都必须正确的执行了初始化才能够正常的工作 2.__init__()方法的参数可以多种形式来完成赋 ...