[CSP-S2019]括号树 题解
CSP-S2 2019 D1T2
刚开考的时候先大概浏览了一遍题目,闻到一股浓浓的stack气息
调了差不多1h才调完,加上T1用了1.5h+ 然而T3还是没写出来,滚粗
思路分析
很容易想到的常规操作,把“(”用1、“)”用-1表示。
可以想到一种暴力的做法,不断从根节点向下暴力匹配,同时统计合法个数。至于如何匹配,看到括号匹配,很自然就想到开个栈来存储从根节点到当前节点的括号,当当前节点与栈顶匹配,就把栈顶弹出,答案自加。
这个题目比较好处理的一点就是如果一个合法括号内有不合法的也是不能计入答案的,这个大大降低了处理的难度。~~至少对于我这种蒟蒻是这样~~
很显然,每次从根节点重新统计过于浪费时间。可以想到,对于非根节点的所有节点,答案一定不小于其父亲节点的答案,也就是说,从根节点到其父亲节点可行的合法括号串,到该节点一样可行。这样就快多了。
还有一种情况,就是几个合法括号串相连构成的合法括号串。和之前一样的思想,从祖先节点往下推:记录以每个节点为结尾的合法括号串个数,每找到一个合法括号串,查询以该串起始节点的父节点为结尾的合法括号串个数,显然,这些括号串加上后面这一个合法括号串是可以构成一个新合法括号串的,再加上最新的这一个,加1即可。
但是还有一个问题,一个节点可能会有多个子节点,而执行dfs时,其中某些子节点会对栈的状态产生影响,导致各个子节点最开始的栈状态不同。因此,在回溯前要将栈恢复到原来的状态。这个很好实现,只要将原本删掉的节点加回去即可。
这样就结束了。不会很难,细节稍多,不过样例很良心,基本能够调出所有的bug。
最后吐槽一下把我电脑臭爆栈的大样例 现在洛谷上臭不到,但是T1...
可以看出大样例就是一条链,并且链上就是类似“()()()...()()()”这样的,实际上意义不大,爆栈了测不了也不要紧,实现的时候完全可以用一个类似的小样例来测。大样例唯一的作用就是提醒我要开long long 。
#include<iostream>
#include<cstdio>
#include<stack>
#define ll long long
using namespace std;
const int N=5e5+1000;
int n,tot;
ll ans;
int head[N],ver[N],Next[N];
int w[N],f[N];
ll tail[N],sum[N];
bool v[N];
char c;
stack<int> q;
void add(int x,int y)
{
ver[++tot]=y,Next[tot]=head[x],head[x]=tot;
}
void dfs(int x)
{
int y=0;
if(q.size() && w[q.top()]+w[x]==0 && w[x]==-1)
{
y=q.top();q.pop();v[y]=0;
tail[x]=tail[f[y]]+1;
}
else
q.push(x),v[x]=1;
sum[x]=sum[f[x]]+tail[x];
for(int i=head[x];i;i=Next[i])
dfs(ver[i]);
if(v[x])
q.pop(),v[x]=0;
if(y)
q.push(y),v[y]=1;
}
int main()
{
scanf("%d",&n);q.push(0);
for(int i=0;i<n;i++)
{
cin>>c;
if(c=='(')
w[i+1]=1;
else
w[i+1]=-1;
}
for(int i=2;i<=n;i++)
{
scanf("%d",&f[i]);
add(f[i],i);
}
dfs(1);
for(int i=1;i<=n;i++)
ans^=(ll)i*sum[i];
printf("%lld",ans);
return 0;
}
[CSP-S2019]括号树 题解的更多相关文章
- 上午小测3 T1 括号序列 && luogu P5658 [CSP/S 2019 D1T2] 括号树 题解
前 言: 一直很想写这道括号树..毕竟是在去年折磨了我4个小时的题.... 上午小测3 T1 括号序列 前言: 原来这题是个dp啊...这几天出了好几道dp,我都没看出来,我竟然折磨菜. 考试的时候先 ...
- 【CSP2019】括号树 题解(递推+链表)
前言:抽时间做了做这道题,把学长送退役的题. ----------------- 题目链接 题目大意:定义$()$是合法括号串.如果$A,B$是合法括号串,那么$(AB),AB$为合法括号串.现给定根 ...
- 洛谷 P5658 括号树 题解
原题链接 简要题意: 求出以从每个节点到根形成的括号序列的合法对数. 算法一 观察到 \(n \leq 8\) ,所以我们可以用 纯粹的暴力 . 用 \(O(n)\) 时间得出当前节点到根的字符串. ...
- P5658 括号树
P5658 括号树 题解 太菜了啥都不会写只能水5分数据 啥都不会写只能翻题解 题解大大我错了 我们手动找一下规律 我们设 w[ i ] 为从根节点到结点 i 对答案的贡献,也就是走到结点 i ,合 ...
- Vijos1448校门外的树 题解
Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...
- [CSP-S 2019]括号树
[CSP-S 2019]括号树 源代码: #include<cstdio> #include<cctype> #include<vector> inline int ...
- CSP2019 括号树
Description: 给定括号树,每个节点都是 ( 或 ) ,定义节点的权值为根到该节点的简单路径所构成的括号序列中不同合法子串的个数(子串需要连续,子串所在的位置不同即为不同.)与节点编号的乘积 ...
- 2021.08.09 P5658 括号树(树形结构)
2021.08.09 P5658 括号树(树形结构) [P5658 CSP-S2019] 括号树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 太长,在链接中. 分析及代码 ...
- 题解【洛谷P5658】[CSP-S 2019]括号树
题面 一道简单的栈与\(\text{DP}\)的结合. 首先介绍一下序列上的括号匹配问题,也就是此题在序列上的做法: 设 \(dp_i\) 表示以 \(i\) 结尾的合法的括号序列个数, \(ss_i ...
随机推荐
- Python os.dup() 方法
概述 os.dup() 方法用于复制文件描述符 fd.高佣联盟 www.cgewang.com 语法 dup()方法语法格式如下: os.dup(fd); 参数 fd -- 文件描述符 返回值 返回复 ...
- PHP ftp_size() 函数
定义和用法 ftp_size() 函数返回 FTP 服务器上指定文件的大小. 该函数以字节返回指定文件的大小,如果出错则返回 -1. 语法 ftp_size(ftp_connection,file) ...
- mysql优化:explain 和 profile
此文转自:https://blog.csdn.net/hanjungua8144/article/details/84317829 一.SQL查询语句优化基本思路和原则 优化更需要优化的Query.定 ...
- MySQL 笔记 —— 中文乱码解决、修改mysql服务端编码
https://blog.csdn.net/qq_19865749/article/details/79235422
- JAVA设计模式 5【结构型】代理模式的理解与使用
今天要开始我们结构型 设计模式的学习,设计模式源于生活,还是希望能通过生活中的一些小栗子去理解学习它,而不是为了学习而学习这些东西. 结构型设计模式 结构型设计模式又分为 类 结构型 对象 结构型 前 ...
- [转]Nginx限流配置
原文:https://www.cnblogs.com/biglittleant/p/8979915.html 作者:biglittleant 1. 限流算法 1.1 令牌桶算法 算法思想是: 令牌以固 ...
- day8.列表、字典、集合相关操作
一.列表的相关操作 # (1)列表的拼接 (同元组) # (2)列表的重复 (同元组) # (3)列表的切片 (同元组) # 语法 => 列表[::] 完整格式:[开始索引:结束索引:间隔值] ...
- Linux-sed命令使用笔记
Linux的sed命令和python脚本一起,可以对文本进行快速的修改.比如在删除日志的时候,python写出固定日期删除脚本,再用sed循环将python脚本的日期修改调用,就可以批删除指定日期的日 ...
- Python最全pdf学习书籍资料分享
本人学习Python两年时间,期间统计了一些比较好的学习资料 1.基础资料 下载地址: 链接:https://pan.baidu.com/s/1sjtyYayBbQLsrUdaXWmzkg提取码:1 ...
- python爬取高匿代理IP(再也不用担心会进小黑屋了)
为什么要用代理IP 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识.那么针对这三类人 ...