51nod 1791 合法括号子段
因为在括号串固定的情况下,括号的匹配是固定不变的。所以对左括号进行匹配,p[i]表示与i这个括号相匹配的括号的位置,易得到dp方程 ans[i]=ans[p[i]+1]+1,然后再从后先前一遍求和即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1100005;
char c[N];
ll ans[N];
int p[N];
int s[N];
int top;
int t;
int main() {
ios::sync_with_stdio(false);
cin>>t;
while(t--){
cin>>(c+1);
int n=strlen(c+1),top=0;
for(int i=1;i<=n;i++){
p[i]=-1;
}
for(int i=1;i<=n;i++){
if(c[i]=='('){
s[++top]=i;
}
else if(top){
p[s[top--]]=i;
}
}
ll sum=0;
for(int i=n;i>=1;i--){
if(p[i]==-1){
ans[i]=0;
}
else{
ans[i]=ans[p[i]+1]+1;
}
sum+=ans[i];
}
cout<<sum<<"\n";
}
return 0;
}