题目大意
给出T个长度为n 只包含左括号和右括号的序列
现在要求每个序列经过每一个位置的合法子串有多少个。
空串是一个合法的串,如果A 和B 都是合法的串,那么(A) 和AB 都是合法的串。
题目解析
首先利用栈来求出括号匹配
利用拆分序列(不懂,该补课了)
然后把两个序列相加,再加前缀和
利用这个公式求出答案即可
代码
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
int T,n;
int l[N],r[N],x[N],y[N];
long long ans,sum[N];
char c[N];
stack<int> a;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%s",c+1);
n=strlen(c+1);
while(!a.empty()) a.pop();
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++)
if(c[i]=='(')
a.push(i);
else if(!a.empty())
{
r[a.top()]=i+1;
l[i+1]=a.top();
a.pop();
}
for(int i=n+1;i>=1;i--)
{
y[i]++;
y[l[i]]+=y[i];
}
for(int i=1;i<=n;i++)
{
x[i]--;
x[r[i]]+=x[i];
}
for(int i=1;i<=n;i++)
sum[i]=x[i]+y[i];
for(int i=1;i<=n;i++)
sum[i]+=sum[i-1];
ans=0;
for(int i=1;i<=n;i++)
ans+=(long long)i*sum[i]%1000000007;
cout<<ans<<endl;
}
}