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]括号树 题解的更多相关文章

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

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

  2. 【CSP2019】括号树 题解(递推+链表)

    前言:抽时间做了做这道题,把学长送退役的题. ----------------- 题目链接 题目大意:定义$()$是合法括号串.如果$A,B$是合法括号串,那么$(AB),AB$为合法括号串.现给定根 ...

  3. 洛谷 P5658 括号树 题解

    原题链接 简要题意: 求出以从每个节点到根形成的括号序列的合法对数. 算法一 观察到 \(n \leq 8\) ,所以我们可以用 纯粹的暴力 . 用 \(O(n)\) 时间得出当前节点到根的字符串. ...

  4. P5658 括号树

    P5658 括号树 题解 太菜了啥都不会写只能水5分数据 啥都不会写只能翻题解  题解大大我错了 我们手动找一下规律 我们设 w[ i ] 为从根节点到结点 i 对答案的贡献,也就是走到结点 i ,合 ...

  5. Vijos1448校门外的树 题解

    Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...

  6. [CSP-S 2019]括号树

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

  7. CSP2019 括号树

    Description: 给定括号树,每个节点都是 ( 或 ) ,定义节点的权值为根到该节点的简单路径所构成的括号序列中不同合法子串的个数(子串需要连续,子串所在的位置不同即为不同.)与节点编号的乘积 ...

  8. 2021.08.09 P5658 括号树(树形结构)

    2021.08.09 P5658 括号树(树形结构) [P5658 CSP-S2019] 括号树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 太长,在链接中. 分析及代码 ...

  9. 题解【洛谷P5658】[CSP-S 2019]括号树

    题面 一道简单的栈与\(\text{DP}\)的结合. 首先介绍一下序列上的括号匹配问题,也就是此题在序列上的做法: 设 \(dp_i\) 表示以 \(i\) 结尾的合法的括号序列个数, \(ss_i ...

随机推荐

  1. ElasticJob和SpringBoot

    本文以在SpringBoot下集成ElasticJob的方式对其进行浅析,仅仅是简单使用,不涉及源码级别研究. 事先必备: 注册中心——zookeeper 简略结构: 代码目录结构: ├─.idea ...

  2. 4.15 省选模拟赛 编码 trie树 前缀和优化建图 2-sat

    好题 np. 对于20分 显然可以爆搜. 对于50分 可以发现每个字符串上的问号要么是0,要么是1.考虑枚举一个字符串当前是0还是1 这会和其他字符串产生矛盾. 所以容易 发现这是一个2-sat问题. ...

  3. react ts redux-saga | 谷歌Chrome浏览器风格的标签组件 | 中台

    谷歌Chrome浏览器风格的标签组件 选用技术 react typescript redux-saga存储本地标签数据 umi 实现 [x] 支持全部关闭,当前关闭,关闭其他Tab [x] 支持Tab ...

  4. 强烈推荐的 IntelliJ IDEA 插件,别说我没告诉你

    为什么你的 Intellij IDEA 没别人的好用?还不是因为你缺少这几个插件啊! 善用 Intellij IDEA 插件可以提高我们的开发效率,今天和大家一起分享一下实际工作中常用的几款能提升幸福 ...

  5. day23:单继承&多继承&菱形继承&__init__魔术方法

    1.单继承 1.1 关于继承的一些基本概念 1.2 子类可以调用父类的公有成员 1.3 子类无法调用父类的私有成员 1.4 子类可以改写父类的方法 2.多继承 2.1 多继承的基本语法 2.2 sup ...

  6. String 的两种实例化方式

    String 的两种实例化方式 隐式实例化:直接赋值 public class Demo { public static void main(String[] args) { String s = & ...

  7. NIO(三):Selector选择器

    一.堵塞式与非堵塞式 在传统IO中,将数据由当前线程从客户端传入服务端,由服务端的内核进行判断传过来的数据是否合法,内核中是否存在数据. 如果不存在数据 ,并且数据并不合法,当前线程将会堵塞等待.当前 ...

  8. jenkins集成spring boot持续化构建代码

    我个人使用的是阿里云的云服务器,项目采用的是spring boot为框架,现在要做的功能就是将本地开发的代码提交到github中,通过jenkins自动化集成部署到云服务器.接下来开始步骤. 1 首先 ...

  9. one of the variables needed for gradient computation has been modified by an inplace operation: [torch.cuda.FloatTensor [3, 1280, 28, 28]], which is output 0 of LeakyReluBackward1, is at version 2;

    RuntimeError: one of the variables needed for gradient computation has been modified by an inplace o ...

  10. C#LeetCode刷题之#263-丑数(Ugly Number)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3862 访问. 编写一个程序判断给定的数是否为丑数.丑数就是只包含 ...