a[i] 表示以i字符开头的合法序列有多少个
b[i] 表示以i字符结尾的合法序列有多少个
up表示上一层的'('的对应位置
mt[i] i匹配的对应位置
c[i] 包含i字符的合法序列个数 c[i]=c[up[i]]+a[i]*b[mt[i]]
括号序列不一定是合法的....
Easy Sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 557 Accepted Submission(s): 165
Problem Description
soda has a string containing only two characters -- '(' and ')'. For every character in the string, soda wants to know the number of valid substrings which contain that character.
Note:
An empty string is valid. If S is valid, (S) is valid. If U,V are valid, UV is valid.
Note:
An empty string is valid. If S is valid, (S) is valid. If U,V are valid, UV is valid.
Input
There are multiple test cases. The first line of input contains an integer
T
, indicating the number of test cases. For each test case:
A string s consisting of '(' or ')' (1≤|s|≤106) .
A string s consisting of '(' or ')' (1≤|s|≤106) .
Output
For each test case, output an integer
m=∑i=1|s|(i⋅ansi mod 1000000007)
, where
ansi
is the number of valid substrings which contain
i
-th character.
Sample Input
2 ()() ((()))
Sample Output
20 42HintFor the second case, ans={1,2,3,3,2,1} , then m=1⋅1+2⋅2+3⋅3+4⋅3+5⋅2+6⋅1=42
Source
/* ***********************************************
Author :CKboss
Created Time :2015年08月10日 星期一 14时24分51秒
File Name :HDOJ5357_2.cpp
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef long long int LL;
const int maxn=1001000;
const LL mod=1e9+7;
int n;
LL a[maxn],b[maxn],mt[maxn];
LL c[maxn];
int up[maxn];
int stk[maxn],top;
char str[maxn];
void init(int n)
{
top=0;
memset(mt,0,sizeof(mt[0])*n);
memset(a,0,sizeof(a[0])*n);
memset(b,0,sizeof(b[0])*n);
memset(c,0,sizeof(c[0])*n);
memset(up,0,sizeof(up[0])*n);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T_T;
scanf("%d",&T_T);
while(T_T--)
{
scanf("%s",str+1);
n=strlen(str+1);
init(n+10);
for(int i=1;i<=n;i++)
{
if(str[i]=='(')
{
up[i]=stk[top];
stk[++top]=i;
}
else if(top)
{
int u=stk[top--];
mt[u]=i; mt[i]=u;
b[i]=b[mt[i]-1]+1;
}
}
while(top) mt[stk[top--]]=0;
for(int i=n;i>=1;i--)
{
if(str[i]=='('&&mt[i])
{
a[i]=a[mt[i]+1]+1;
}
}
LL ans=0; c[0]=0;
for(int i=1;i<=n;i++)
{
if(str[i]=='('&&mt[i])
{
c[mt[i]]=c[i]=c[up[i]]+(LL)a[i]*b[mt[i]];
}
ans+=c[i]*i%mod;
}
cout<<ans<<endl;
}
return 0;
}