有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。合法括号序列的定义是:
- 空序列是合法括号序列。
- 如果S是合法括号序列,那么(S)是合法括号序列。
- 如果A和B都是合法括号序列,那么AB是合法括号序列。
思路:用栈记录每一个左括号的位置,r数组记录左括号对应的最近右括号的位置
递推过程:当遇到左括号时,若存在对应的右括号,则f[i]=f[r[i]+1]+1,代表i位置的合法括号字段多了一个
r[i]+1:因为r[i]+1可能就是后面一个合法括号字段的开始,对应已满第3点
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1100005;
ll f[N],r[N];
int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t; cin>>t;
while (t--) {
string s; cin>>s;
ll n=s.size(),ans=0; fill(f,f+n,0), fill(r,r+n,-1);
stack<int> st;
for (int i=0; i<n; i++) {
if (s[i]=='(') st.push(i);
else if (!st.empty()) r[st.top()]=i, st.pop();
}
for (int i=n-1; ~i; i--) {
if (r[i]!=-1) f[i]=f[r[i]+1]+1;
else f[i]=0;
ans+=f[i];
}
cout<<ans<<'
';
}
return 0;
}