传送门:QAQ
题意:让你改变序列的一个括号,让它成为合法的序列,问你总共有多少种方案
思路:首先要知道当右括号的数量超过左括号的数量时,我们必须改这个位置,然后可能虽然存在你把前面改合法了,但是后面仍然是不合法的,所以我们既要知道该位置前面的状态和后面的状态,这里可以采用维护前缀和和后缀和数组,我在这里将后面的影响提到前面的位置,这样就可以正确的限制该位置的修改。
附上代码:
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
#define pi acos(-1.0)
#define inf 0x3f3f3f3f
char ch[1000100];
int cnt[1000100];
int gg[1000100];
int main(void) {
int n;
scanf("%d", &n);
getchar();
for (int i = 1; i <= n; i++) {
scanf("%c", &ch[i]);
}
memset(cnt, 0, sizeof(cnt));
for (int i = 1; i <= n; i++) {
if (ch[i] == '(') {
cnt[i] = cnt[i - 1] + 1;
}
else {
cnt[i] = cnt[i - 1] - 1;
}
gg[i] = cnt[i];
}
if (!(cnt[n] == 2 || cnt[n] == -2)) {
printf("0\n");
return 0;
}
int ans = 0;
for (int i = n - 1; i >= 1; i--) {
cnt[i] = min(cnt[i], cnt[i + 1]);
}
for (int i = 1; i <= n; i++) {
if (cnt[i] >= 2 && cnt[n] == 2 && ch[i] == '(') {
ans++;
}
else if (cnt[i] >= -2 && cnt[n] == -2 && ch[i] == ')') {
ans++;
}
if (gg[i] < 0) {
break;
}
}
printf("%d\n", ans);
}