您的位置:首页 > 其它

【51Nod1791】合法括号子段

2017-09-13 20:33 351 查看
有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。

合法括号序列的定义是:

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

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

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

Input

多组测试数据。

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

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

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

Output

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

Input示例

5

(

()

()()

(()

(())

Output示例

0

1

3

1

2

题解

利用栈使得每次配对都是最近的,同时记录下方案数。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<set>
#include<ctime>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#define mod 1000000007
#define ll long long
#define N 10000005
#define inf 0x7fffffff
using namespace std;
inline int read()
{
int 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;
}
char s[110005];
int num[110005];
inline void solve()
{
scanf("%s",s+1);
int n=strlen(s+1);
ll ans=0;
stack<int>q;
for (int i=1;i<=n;i++) num[i]=0;
for (int i=1;i<=n;i++)
if (s[i]=='(') q.push(i);
else
{
if (q.empty()) continue;
int p=q.top();
ans+=(ll)num[p-1]+1;
num[i]=num[p-1]+1;
q.pop();
}
printf("%lld\n",ans);
}
int main()
{
int Case=read();
while (Case--) solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: