D. Invertible Bracket Sequences

原题链接

题解

把(当作+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;
}
posted @ 2024-06-20 17:50  纯粹的  阅读(40)  评论(0)    收藏  举报