[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 ...
随机推荐
- PHP end() 函数
实例 输出数组中的当前元素和最后一个元素的值: <?php$people = array("Peter", "Joe", "Glenn" ...
- PHP max() 函数
实例 通过 max() 函数查找最大值: <?phpecho(max(2,4,6,8,10) . "<br>");echo(max(22,14,68,18,15) ...
- 5.4 省选模拟赛 修改 线段树优化dp 线段树上二分
LINK:修改 题面就不放了 大致说一下做法.不愧是dls出的题 以前没见过这种类型的 不过还是自己dp的时候写丑了. 从这道题中得到一个结论 dp方程要写的优美一点 不过写的过丑 优化都优化不了. ...
- SpringBoot之多模块项目
SpringBoot之多模块项目 说明:我们通过maven的父子工程来搭建springboot的多模块项目** 项目的整体结构 本项目涉及了到了五个模块 framework-web模块主要是放置前端的 ...
- OAuth2.0-4整合网关
.antMatchers("/**").access("#oauth2.hasScope('scope1')")上面这行代码,只是控制大范围的访问权限,具体到方 ...
- 021_go语言中的异常处理
代码演示 package main import ( "errors" "fmt" ) // Go语言里面约定错误代码是函数的最后一个返回值, // 并且类型是 ...
- 团队项目-记账App
一.团队成员介绍 队长: 向瑜 博客园地址: https://www.cnblogs.com/xiangyu721/ 沟通能力较强,善于总结,能够正确分配团队任务.其次,有耐心学习新事物,发现新问题 ...
- 铁大树洞APP视频讲解和原型演示
首先放上我们团队视频讲解演示的视频:https://v.youku.com/v_show/id_XNDYyMzA3MTgzNg==.html 团队名称:超能陆战队 团队成员:刘梦鑫(队长) 段行行 徐 ...
- JavaScript calss语法糖
JavaScript calss语法糖 基础知识 严格意义上来讲,在Js中是没有类这一概念的. 我们可以运用前面章节提到的构造函数来模拟出类这一概念,并且可以通过原型对象的继承来完美的实现实例对象方法 ...
- System.out.println()相关源码
System.out.println是一个Java语句,一般情况下是将传递的参数,打印到控制台. System:是 java.lang包中的一个final类.根据javadoc,“java.lang. ...