题面

一道简单的栈与\(\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]括号树的更多相关文章

  1. 上午小测3 T1 括号序列 && luogu P5658 [CSP/S 2019 D1T2] 括号树 题解

    前 言: 一直很想写这道括号树..毕竟是在去年折磨了我4个小时的题.... 上午小测3 T1 括号序列 前言: 原来这题是个dp啊...这几天出了好几道dp,我都没看出来,我竟然折磨菜. 考试的时候先 ...

  2. 洛谷 P3373 【模板】线段树 2

    洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...

  3. [CSP-S 2019]括号树

    [CSP-S 2019]括号树 源代码: #include<cstdio> #include<cctype> #include<vector> inline int ...

  4. 括号树 noip(csp??) 2019 洛谷 P5658

    洛谷AC通道 本题,题目长,但是实际想起来十分简单. 首先,对于树上的每一个后括号,我们很容易知道,他的贡献值等于上一个后括号的贡献值 + 1.(当然,前提是要有人跟他匹配,毕竟题目中要求了,是不同的 ...

  5. 题解 洛谷P5018【对称二叉树】(noip2018T4)

    \(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...

  6. 题解 洛谷 P3396 【哈希冲突】(根号分治)

    根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...

  7. 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)

    题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...

  8. 题解-洛谷P4229 某位歌姬的故事

    题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...

  9. 题解-洛谷P4724 【模板】三维凸包

    洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...

随机推荐

  1. 监控redis cluster 主从实例是否切换,切换前后对应关系

    需求:编写脚本实现对redis cluster 主从是否发生主从切换进行监控,若发生切换,输出切换前后主从对应关系. 初始化对比文件,仅执行一次,后续不需要在执行,除非该文件不存在. cmd=&quo ...

  2. netty 4.x用户使用指南

    引言 问题 现在我们使用通用的应用程序或库来相互通信.例如,我们经常使用HTTP客户机从web服务器检索信息,并通过web服务调用远程过程调用.然而,通用协议或其实现有时不能很好地进行扩展.这就像我们 ...

  3. Wannafly Winter Camp 2020 Day 6I 变大! - dp

    给定一个序列,可以执行 \(k\) 次操作,每次选择连续的三个位置,将他们都变成他们的最大值,最大化 \(\sum a_i\) 需要对每一个 \(k=i\) 输出答案 \(n \leq 50, a_i ...

  4. 侧信道攻击,从喊666到入门之——Unicorn的环境构建

    作者:backahasten 发表于小米安全中心微信公众号 0x00 前言 Unicorn可以模拟多种指令集的代码,在很多安全研究领域有很强大的作用,但是由于需要从头自己布置栈空间,代码段等虚拟执行环 ...

  5. BSP与HAL关系(转)

    板级支持包(BSP)(Board Support Package)是介于主板硬件和操作系统中驱动层程序之间的一层,一般认为它属于操作系统一部分,主要是实现对操作系统的支持,为上层的驱动程序提供访问硬件 ...

  6. (int)、int.Parse()、int.TryParse()、Convert.ToInt32()区别

    请看代码: //1.null. //int i1 = (int)null;//编译时报错:无法将“null”转换为“int”,因为后者是不可以为“null”的值类型. //int i2 = int.P ...

  7. Math, Date,JSON对象

    Math 对象 Math是 JavaScript 的原生对象,提供各种数学功能.该对象不是构造函数,不能生成实例,所有的属性和方法都必须在Math对象上调用. 静态属性 Math对象的静态属性,提供以 ...

  8. paramiko 基于密钥文件登陆

    首先密钥登陆远程的原理 client 端 将公钥放在远程机器authorized_keys: 使用 ssh-copy-id  app@ip 接着在client机器生成密钥 使用ssh-keygen - ...

  9. BZOJ 2306: [Ctsc2011]幸福路径

    Description 有向图 G有n个顶点 1, 2, -, n,点i 的权值为 w(i).现在有一只蚂蚁,从 给定的起点 v0出发,沿着图 G 的边爬行.开始时,它的体力为 1.每爬过一条 边,它 ...

  10. dev 控件用法2 之repositoryItemSearchLookUpEdit

    repositoryItemSearchLookUpEdit var y = userinfo.Select.ToList( a => new { userid = a.userid, code ...