CSP-S 2019 括号树
\(\text{括号树}\)
本题中合法括号串的定义如下:
\(()\) 是合法括号串。
如果 \(A\) 是合法括号串,则\((A)\) 是合法括号串。
如果 \(A\),\(B\) 是合法括号串,则 \(AB\) 是合法括号串。
小 \(Q\) 定义 \(s_i\)为:将根结点到\(i\)号结点的简单路径上的括号,按结点经过顺序依次排列组成的字符串。
设\(s_i\)共有\(k_i\)个不同子串是合法括号串, 你只需要告诉小 Q 所有 \(i * k_i\)的\(xor\)值
subtask1 \(\text {期望得分 10pts}\)
\(O(n^2)\)枚举区间 \(O(n^2)\)判断 时间复杂度\(O(n ^ 4)\)
subtask2 \(\text {期望得分 55 pts}\)
链上的部分分 因为是合法括号序列数 可以考虑动态规划
用栈辅助维护第\(i\)个括号可以对应匹配的括号序列数\(cnt[i]\)
\[f[i] = f[pre[i]] + cnt[i]
\]
时间复杂度\(O(n)\)
std \(\text {期望得分 100pts}\)
想到链\(55pts\)正解应该也能想出来
\[f[u] = f[fa[tmp]] + cnt[u]
\]
inline void dfs (int u) {
int tmp = 0;
if (ch[u] == ')') {
if (top) {
tmp = s[top];
f[u] = f[fa[tmp]] + 1;
top -- ;
}
} else if (ch[u] == '(') s[++top] = u;
sum[u] = sum[fa[u]] + f[u];
for (int i = head[u]; i; i = edge[i].next) dfs (edge[i].to);
if (tmp) {
s[++top] = tmp;
} else if (top) top -- ;
}
分析
暴力\(55\)貌似不难\(O(n ^ 2)\)就行了
想到链的部分分后正解就不是特别难 评级为 提高/提高+