大意:给定字符串, 只含'(',')','?', 其中'?'可以替换为'('或')', 求有多少个子串可以的括号可以匹配 (不同子串之间独立)
记$s_($为'('个数, $s_)$为')'个数.
一个括号串匹配等价于长度为偶数, 且任意一个前缀中$s_( \ge s_)$,任意一个后缀中$s_) \ge s_($.
对前缀后缀分别暴力判断即可
#include <iostream>
#include <algorithm>
#include <cstdio>
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define REP(i,a,n) for(int i=a;i<=n;++i)
using namespace std;
const int N = 5e3+10, INF = 0x3f3f3f3f;
int n;
int cnt[N][N], a[N];
char s[N];
int main() {
scanf("%s", s+1);
n = strlen(s+1);
REP(i,1,n) {
int t = 0;
REP(j,i,n) {
t += s[j]==')';
if (t>j-i+1-t) break;
++cnt[i][j];
}
}
int ans = 0;
PER(i,1,n) {
int t = 0;
PER(j,1,i) {
t += s[j]=='(';
if (t>i-j+1-t) break;
if (++cnt[j][i]==2&&(i-j)%2) ++ans;
}
}
printf("%d\n", ans);
}