码迷,mamicode.com
首页 > 其他好文 > 详细

CSP-S 2019 括号树

时间:2020-01-19 12:55:49      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:for   oid   isp   --   span   应该   head   ==   判断   

\(\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)\)就行了
想到链的部分分后正解就不是特别难 评级为 提高/提高+

CSP-S 2019 括号树

标签:for   oid   isp   --   span   应该   head   ==   判断   

原文地址:https://www.cnblogs.com/Hock/p/12213090.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!