题解:P16958 [SCCPC 2026] 括号序列
stripe_python · · 题解
给定合法括号串
S ,求有多少合法括号串T 满足|T| \le |S| 且T 的字典序不大于S 。对998244353 取模。多测,
\sum |S| \le 10^6 ,2 秒,1024 MB。
我们将括号串转化成格路。将左括号视作
特判
在 LCP 之后
转而枚举
我们记
则
瓶颈在于
我们需要观察
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1 10
0 0 0 0 0 0 1 9 54
0 0 0 0 0 1 8 44 209
0 0 0 0 1 7 35 155 650
0 0 0 1 6 27 111 441 1728
0 0 1 5 20 76 286 1078 4081
0 1 4 14 49 175 637 2353 8788
注意到以下等式成立:
而
维护
注意到
复杂度
const int N = 1e6 + 5;
int n; char s[N];
comb<mint, N+5> C(N);
struct node {
int a, b;
mint u, v;
// u = f(a, b) v = f(a+1, b)
node(int _a, int _b) : a(_a), b(_b), u(0), v(0) {
for (int k = 0; k <= b; k++) u += C(2*k+a, k), v += C(2*k+a+1, k);
}
void sub_b() {
u -= C(2*b+a, b), v -= C(2*b+a+1, b), b--;
}
void add_a() {
a++, tie(u, v) = make_pair(v, v - u + C(2*b+a+1, b));
}
void sub_a() {
tie(u, v) = make_pair(u - v + C(2*b+a+1, b), u), a--;
}
};
void _main() {
cin >> n >> (s + 1); n /= 2;
node A(-1, n), B(-3, n+1);
mint res = 0;
for (int i = 1, x = 0, y = 0; i <= 2*n; i++) {
if (s[i] == ')') res += A.u - B.u;
if (s[i] == '(') x++, A.sub_a(), B.sub_a();
else y++, A.add_a(), B.add_a(), A.sub_b(), B.sub_b();
if (x == y) res += 1;
}
cout << res << '\n';
}