题解【洛谷P5658】[CSP-S 2019]括号树
一道简单的栈与\(\text{DP}\)的结合。
首先介绍一下序列上的括号匹配问题,也就是此题在序列上的做法:
- 设 \(dp_i\) 表示以 \(i\) 结尾的合法的括号序列个数, \(ss_i\) 表示 \(1\) 到 \(i\) 合法的括号序列字串个数。
- 维护一个栈,左括号 \(\text{push}\) 它的位置到栈中,右括号取出栈顶 \(dp_i = dp_{sta_{top} - 1} + 1\) , 然后 \(ss_i=ss_{i-1}+dp_{i}\)。
- 答案即为 \((1\times ss_1) \oplus (2 \times ss_2) \oplus \dots \oplus (n \times ss_n)\) ,其中 \(\oplus\) 为异或。
考虑将这个问题转移到树上,只需要一个可回退的栈即可。
这题真的不难,我考场上为什么没想出来啊
我太菜了
代码:
#include <bits/stdc++.h>
#define itn int
#define gI gi
#define int long long
using namespace std;
inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return f * x;
}
const int maxn = 500003;
int n, ans, topp, ss[maxn], dp[maxn], sta[maxn], sum[maxn];
int fa[maxn], tot, head[maxn], ver[maxn * 2], nxt[maxn * 2];
char s[maxn];
inline void add(int u, int v) {ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;}
void dfs(int u, int f)
{
int fl = -1;
if (s[u] == '(') sta[++topp] = u; //左括号加入栈
else if (topp > 0) //右括号且栈中有对应的左括号
{
fl = sta[topp--]; //栈顶元素
dp[u] = dp[fa[fl]] + 1; //dp 数组记得 +1
}
sum[u] = sum[fa[u]] + dp[u]; //sum[u] 表示 1 到 u 的路径上合法括号序列的个数
for (int i = head[u]; i; i = nxt[i])
{
int v = ver[i];
if (v == f) continue;
dfs(v, u);
}
//将栈还原到访问节点 u 之前的状态
if (s[u] == '(') --topp;
else if (fl != -1)
{
sta[++topp] = fl;
}
}
signed main()
{
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
n = gi();
scanf("%s", s + 1);
bool fl = true;
for (int i = 2; i <= n; i+=1)
{
fa[i] = gi();
if (fa[i] != i - 1) fl = false;
add(fa[i], i), add(i, fa[i]);
}
if (fl) //序列上的做法
{
for (int i = 1; i <= n; i+=1)
{
if (s[i] == '(') sta[++topp] = i;
else if (topp) dp[i] = dp[sta[topp--] - 1] + 1;
ss[i] = ss[i - 1] + dp[i];
ans ^= (i * ss[i]);
}
printf("%lld\n", ans);
return 0;
}
dfs(1, 0);
for (int i = 1; i <= n; i+=1) ans ^= (i * sum[i]);
printf("%lld\n", ans);
return 0;
}
题解【洛谷P5658】[CSP-S 2019]括号树的更多相关文章
- 上午小测3 T1 括号序列 && luogu P5658 [CSP/S 2019 D1T2] 括号树 题解
前 言: 一直很想写这道括号树..毕竟是在去年折磨了我4个小时的题.... 上午小测3 T1 括号序列 前言: 原来这题是个dp啊...这几天出了好几道dp,我都没看出来,我竟然折磨菜. 考试的时候先 ...
- 洛谷 P3373 【模板】线段树 2
洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...
- [CSP-S 2019]括号树
[CSP-S 2019]括号树 源代码: #include<cstdio> #include<cctype> #include<vector> inline int ...
- 括号树 noip(csp??) 2019 洛谷 P5658
洛谷AC通道 本题,题目长,但是实际想起来十分简单. 首先,对于树上的每一个后括号,我们很容易知道,他的贡献值等于上一个后括号的贡献值 + 1.(当然,前提是要有人跟他匹配,毕竟题目中要求了,是不同的 ...
- 题解 洛谷P5018【对称二叉树】(noip2018T4)
\(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...
- 题解 洛谷 P3396 【哈希冲突】(根号分治)
根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...
- 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)
题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...
- 题解-洛谷P4229 某位歌姬的故事
题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...
- 题解-洛谷P4724 【模板】三维凸包
洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...
随机推荐
- 洛谷题解 P1292 【倒酒】
原题传送门 题目描述 Winy是一家酒吧的老板,他的酒吧提供两种体积的啤酒,a ml和b ml,分别使用容积为a ml和b ml的酒杯来装载. 酒吧的生意并不好.Winy发现酒鬼们都非常穷.有时,他们 ...
- POJ 3253 Fence Repair 贪心 优先级队列
Fence Repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 77001 Accepted: 25185 De ...
- 【React Native】集成声网Agora语音通讯
前言: 公司的产品是一款基于社交的内容聊天软件,需要集成语音通讯功能,在写iOS原生项目时,用到的就是Agora SDK,现在写React Native也直接采用了Agora的库. 集成iOS.And ...
- js遇到代码出现问题时如何调试代码
单步跟踪调试 debugger; 控制台watch功能查看变量当前值 进入函数操作 随着不断点击,不停进行循环,指定变量的值也在发生改变 添加断点 跳入跳出函数 throw new Error() 主 ...
- 如何利用 WPS Office 进行 IIS Log 分析
找到 IIS Log 打开 Internet Information Service (IIS) Manager 点击左侧 Connections > Sites,在右侧 Sites 列表中定位 ...
- cf1012B
题意简述: 给定一个 n×m的矩阵,其中 q 个位置已经被填充. 有一条规则,如果 (r1,c1) ,(r1,c2),(r2,c1) 均被填充,则 (r2,c2) 也被填充.任何被其他三个位置生成的位 ...
- Lucene使用IKAnalyzer分词
1.分析器 所有分析器最终继承的类都是Analyzer 1.1 默认标准分析器:StandardAnalyzer 在我们创建索引的时候,我们使用到了Index ...
- Mac 配置本地SSL
1,执行: && openssl req -new -sha256 -x509 -days -key server.key -out server.crt 2,生成过程中,其它可随便填 ...
- python字符串前面加上'r'的作用
在打开文件的时候open(r'c:\....') 加r和不加''r是有区别的 'r'是防止字符转义的 如果路径中出现'\t'的话 不加r的话\t就会被转义 而加了'r'之后'\t'就能保留原有的样子 ...
- 【daily】日常所遇 - 页面A嵌套页面B
因为懒,所以直接在http://www.runoob.com写demo测试了. (1)iframe嵌套 虽然可能到现在这中方式都很常用,但是你baidu/google一下会发现.很多人都并不提倡用if ...