题解
把(当作+1,)当作-1,我们可以得到这样的图像
易得要保证翻完之后整体的合法性,\([l,r]\) 内的左右括号数量要相等,在图上看就是 \(pre[l-1]==pre[r]\) 相等
一个合法括号,要保证所有的 \(pre[i]\) 不小于0,因此反过来之后,最小的 \(pre[i]\) 等于 \(pre[r]-\max(pre[k]),k\in(l,r)\)
做法之一:维护每个点为右端点的合法左端点数,并以当前点位最高点更新合法左端点 ,我们用map来记录,这样就保证了每个点作为左端点只会被遍历到一次
code
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
string s;
cin >> s;
s = ' ' + s;
int sum = 0;
map<int, int> q;
q[0] = 1;
long long ans = 0;
for (int i = 1; s[i]; i++) {
sum += (s[i] == ')' ? -1 : 1);
ans += q[sum];
q[sum]++;
while (!q.empty() && q.begin()->first * 2 < sum) {
q.erase(q.begin());
}
}
cout << ans << endl;
}
return 0;
}
标签:pre,Invertible,int,sum,ans,Bracket,端点,Sequences
From: https://www.cnblogs.com/pure4knowledge/p/18259179