有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。

合法括号序列的定义是:

1.空序列是合法括号序列。

2.如果S是合法括号序列,那么(S)是合法括号序列。

3.如果A和B都是合法括号序列,那么AB是合法括号序列。

Input


多组测试数据。

第一行有一个整数T(1<=T<=1100000),表示测试数据的数量。

接下来T行,每一行都有一个括号序列,是一个由'('和')'组成的非空串。

所有输入的括号序列的总长度不超过1100000。

Output


输出T行,每一行对应一个测试数据的答案。

Input示例

5
(
()
()()
(()
(())

Output示例

20
1
3
1
2

题解


对于判断括号序列的合法性,有一种很简洁的方法:

设左括号为-1,右括号为+1,求得一个前缀和数组\(f\)。

那么正确的括号序列必然是以-1开头,0结尾,且中间的数都小于等于零。

知道了这个,此题还需要链表+RMQ操作

首先对于每一个前缀建一个链表\(nxt[f[i]]\)。

假设我们以i为括号序列起点,那么它右边的前缀都得\(-f[i-1]\),那么下一个为0的位置是\(nex[f[i-1]]\),我们已经预处理它的位置

直接RMQ查询即可。诶,这样好像也会超时,最坏情况下也是\(O(n^2)\)的,因为我们会沿着链表跳很多次。。。

那么就倒着做吧,我们记录好以nex[i]为结尾的的答案,以后直接累加即可,至此,时间复杂度降为\(O(nlogn)\)

参考代码

#include <map>
#include <queue>
#include <cmath>
#include <cstdio>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define ll long long
#define inf 1000000000
#define PI acos(-1)
#define REP(i,x,n) for(ll i=x;i<=n;i++)
#define DEP(i,n,x) for(ll i=n;i>=x;i--)
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void Out(ll a){
if(a<0) putchar('-'),a=-a;
if(a>=10) Out(a/10);
putchar(a%10+'0');
}
const int N=1100000+10;
char a[N];
int f[N];
map<int,int> fa;
map<int,int>vis;
int nxt[N];
int dp[N][20];
void RMQ_init(int n){
for(int i=1;i<=n;i++) dp[i][0]=f[i];
for(int j=1;(1<<j)<=n;j++){
for(int i=1;i+(1<<j)-1<=n;i++){
dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
}
int RMQ(int L,int R){
int k=0;
while((1<<(k+1))<=R-L+1) k++;
return max(dp[L][k],dp[R-(1<<k)+1][k]);
}
int main() {
int T=read();
while(T--){
scanf("%s",a+1);
f[0]=0;int n=strlen(a+1);
for(int i=1;i<=n;i++){
if(a[i]=='(') f[i]=f[i-1]-1;
else f[i]=f[i-1]+1;
}
fa.clear();vis.clear();RMQ_init(n);
ll ans=0;
for(int i=n;i>=0;i--){
if(!fa[f[i]]) fa[f[i]]=-1;
nxt[i]=fa[f[i]];
fa[f[i]]=i;
}
vis[-1]=0;
for(int i=n;i>=1;i--){
if(a[i]=='('){
if(nxt[i-1]==-1) vis[i-1]=0;
else{
if(RMQ(i,nxt[i-1])<=f[i-1]) vis[i-1]+=vis[nxt[i-1]]+1;
else vis[i-1]=0;
}
ans+=vis[i-1];
}
}
printf("%lld\n",ans);
}
return 0;
}

【51nod 1791】 合法括号子段的更多相关文章

  1. 51nod 1791 合法括号子段

    有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列. 合法括号序列的定义是: 1.空序列是合法括号序列. 2.如果S是合法括号序列,那么(S)是合法括号序列.3.如果A和B都是合法括号序列, ...

  2. 51 Nod 1791 合法括号子段【分治+字符串】

    1791 合法括号子段 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列. 合法括号序列的定义是: 1. ...

  3. [51nod1791] 合法括号子段 DP

    ---题面--- 题解: 首先我们需要发现一个性质,在括号序列不变的情况下,括号匹配是不会变的,因此不论子串怎么取,括号匹配的关系是不会变化的.这是一个很容易发现的性质,然而我太弱,没发现. 于是可以 ...

  4. 51nod 1065 最小正子段和

    题目链接:51nod 1065 最小正子段和 房教说用前缀和做,然后看了别人博客懂了后就感觉,这个真有意思... #include<cstdio> #include<cstring& ...

  5. [leetcode]32. Longest Valid Parentheses最长合法括号子串

    Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...

  6. 【LeetCode】Valid Parentheses合法括号

    给定一个仅包含 '('.')'.'{'.'}'.'['.']'的字符串,确定输入的字符串是否合法. e.g. "()"."()[]{}"."[()]( ...

  7. 九度oj题目1342:寻找最长合法括号序列II

    题目1342:寻找最长合法括号序列II(25分) 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:886 解决:361 题目描述: 假如给你一个由’(‘和’)’组成的一个随机的括号序列,当然 ...

  8. [Jobdu] 题目1337:寻找最长合法括号序列

    题目描述: 给你一个长度为N的,由’(‘和’)’组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的含义便是,在这个序列中,所有的左括号都有唯一的右括号匹配:所有的右括号都有唯一的 ...

  9. LongestValidParentheses, 求最长合法括号子串长度-----同类问题ValidParentheses,GenerateParentheses

    问题描述:求括号字符串中最长合法子串长度.例如:()((),返回2,而不是4. 算法分析:还是利用栈,和判断合法括号对是一样的. public static int longestValidParen ...

随机推荐

  1. SpringBoot整合Spring Data Solr

    此文不讲solr相关,只讲整合,内容清单如下 1. maven依赖坐标 2. application.properties配置 3. Java Config配置 1. maven坐标 <depe ...

  2. Arthur and Table CodeForces - 557C

    Arthur and Table CodeForces - 557C 首先,按长度排序. 长度为p的桌腿有a[p]个. 要使得长度为p的桌腿为最长,那么要按照代价从小到大砍掉sum{长度不到p的腿的数 ...

  3. luogu P3371 & P4779 单源最短路径spfa & 最大堆优化Dijkstra算法

    P3371 [模板]单源最短路径(弱化版) 题目背景 本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779. 题目描述 如题,给出一个有向图,请输出从某一点出 ...

  4. Eclipse Neon Java版本安装Java EE插件

    Help→Install New Software 地址:Neon - http://download.eclipse.org/releases/neon/201703231000 选择  Web,X ...

  5. php一致性hash性能测试(flexihash/memcache/memcached)

    一致性hash的使用在PHP中有三种选择分别是原生的memcache扩展,memcached扩展,还有一个是网上比较流行的flexihash类. 最近有项目需要使用flexihash类操作memcac ...

  6. 基于ABP的Easyui admin framework正式开放源代码

    下载&反馈:http://www.webplus.org.cn v1.0 (2016/9/21) EF6+MVC5+API2+Easyui1.4.2开发 后台管理不使用iframe,全ajax ...

  7. java课程设计全程实录——第0天

    本次课设计划在5月25日完成.目前还剩18天. 第0天主要完成事项如下: 搭建开发环境 制定开发进度规划表 阅读前人的课设 详细: 1.IDE的下载,安装,以及配合使用的阿里巴巴编程规约插件的安装与测 ...

  8. Android SlidingTabLayout的使用--替代ActionBar的Tab导航

    最近在使用ActionBar的时候,如果使用的是最新版V7包或者最新的SDK平台,就会发现 ActionBar的导航功能已经不建议使用了.主要的原因是ActionBar自带Tab导航自定义性差(只能通 ...

  9. Xilinx器件原语

    原语,其英文名为primitive,是FPGA厂商针对其器件特征开发的一系列常用模块的名称.原语是FPGA芯片中基本元件,代表FPGA中实际拥有的硬件逻辑单元,如LUT,D触发器,RAM等.相当于软件 ...

  10. C#处理Android Audio and Video

    Video Converter for .NET (C#) FFMpeg wrapper http://www.nrecosite.com/video_converter_net.aspx Docum ...