【JZOJ6431】【luoguP5658】【CSP-S2019】括号树

description



analysis

  • 用栈维护一下树上路径未匹配的左括号,然后在树上找右括号匹配,设\(f[i]\)为\(i\)节点的贡献,\(g[i]\)是答案
  • 为左括号可以直接继承父节点的信息,为右括号且栈非空则可以匹配,贡献值是栈顶左括号的父节点的贡献\(+1\)
  • 这个其实就是当前子序列可以拼上左括号父亲的序列,然后每一位的答案就是父节点的答案加上当前点的贡献

code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 500005
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=las[a];i;i=nex[i])

using namespace std;

ll las[MAXN],nex[MAXN],tov[MAXN];
ll f[MAXN],g[MAXN],fa[MAXN],stack[MAXN];
char s[MAXN];
ll n,tot,top,ans;

inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
    while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
inline void link(ll x,ll y){nex[++tot]=las[x],las[x]=tot,tov[tot]=y;}
inline void dfs(ll x)
{
    ll tmp=0;
    if (s[x]=='(')stack[++top]=x;
    else if (top)tmp=stack[top],f[x]=f[fa[tmp]]+1,--top;
    g[x]=g[fa[x]]+f[x],ans^=x*g[x];
    rep(i,x)dfs(tov[i]);
    if (tmp)stack[++top]=tmp;
    else if (top)--top;
}
int main()
{
    n=read(),scanf("%s",s+1);
    fo(i,2,n)link(fa[i]=read(),i);
    dfs(1),printf("%lld\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/horizonwd/p/12051481.html

时间: 2024-07-31 06:38:38

【JZOJ6431】【luoguP5658】【CSP-S2019】括号树的相关文章

P5658 括号树

P5658 括号树 题解 太菜了啥都不会写只能水5分数据 啥都不会写只能翻题解  题解大大我错了 我们手动找一下规律 我们设 w[ i ] 为从根节点到结点 i 对答案的贡献,也就是走到结点 i ,合法括号串又多了几个 sum[ i ] 为从根节点到结点 i 总共合法括号串数 ()()() w[i] 依次为 0  1  0  2  0  3 sum[i] 依次为 0  1  1  3  3  6 ())() w[i] 依次为 0  1  0  0  1 sum[i] 依次为 0  1  1  1

CSP-S 2019 括号树

\(\text{括号树}\) 本题中合法括号串的定义如下: \(()\) 是合法括号串. 如果 \(A\) 是合法括号串,则\((A)\) 是合法括号串. 如果 \(A\),\(B\) 是合法括号串,则 \(AB\) 是合法括号串. 小 \(Q\) 定义 \(s_i\)为:将根结点到\(i\)号结点的简单路径上的括号,按结点经过顺序依次排列组成的字符串. 设\(s_i\)共有\(k_i\)个不同子串是合法括号串, 你只需要告诉小 Q 所有 \(i * k_i\)的\(xor\)值 subtask

CSP2019 括号树

Description: 给定括号树,每个节点都是 ( 或 ) ,定义节点的权值为根到该节点的简单路径所构成的括号序列中不同合法子串的个数(子串需要连续,子串所在的位置不同即为不同.)与节点编号的乘积,求所有节点权值的异或和. Solution: 闻到一股深深的 stack 气息. 懒得写了 Code: #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N = 5e5+1; int n; c

CSP-S2 2019 D1T2 括号树题解

说在前面的话 谨以此篇题解,纪念我初中的两年\(OI\)生涯以及不长不短的停课时光. 但愿高中还能够继续学习\(OI\)吧,也衷心希望其他\(OIer\)不要再犯类似我的错误. 题意 原题链接 给定一棵有\(n\)个节点的树,每个节点对应一个括号(左或右),需要求出从该节点到根节点的简单路径所构成的括号串中合法括号子串的数量. 其中合法括号串的定义是这样的 ()是合法括号串. 如果A是合法括号串,则(A)是合法括号串. 如果A,B是合法括号串,则AB是合法括号串. 其中\(n\le 5\time

Luogu P5658 括号树|搜索+递推

CSP2019 S组D1T2 题目链接 #include<bits/stdc++.h> using namespace std; int cc,to[600000],net[600000],fr[600000],fa[600000],zhan[600000],t,n,nt[600000]; long long s[600000]; char ch[600000];string st;bool vis[600000]; void addedge(int u,int v) { cc++; to[c

CSP-J/S2019试题选做

小蒟蒻duyi CSP爆炸之后一直在颓,所以直到最近才陆续订正完CSP的题/kel 以后不能这么颓了(flag) S D1T2 括号树 设\(f[u]\)表示根到\(u\)的路径上有多少子串是合法括号串.(即题目里的\(k_u\),此变量名缺乏个性,故换之) 从根向每个节点dfs,容易求出\(c[u]\):表示从根到\(u\)的路径上,我们能匹配则匹配,最后剩下多少个待匹配的左括号. 例如如下\(s_u\)对应的\(c[u]\): ((() \(c[u]=2\). (())( \(c[u]=1\

CSP2019游记

——by Nelson 前前夜 秋日降临. 对于我各位亲爱的高中同学们来讲,秋天,意味着井冈山,意味着期中考,意味着这繁忙的高二又过去了四分之一.而我虽然不在什么天边,却也在另一个校园里仰望同一片天空,踌躇着,准备奔向另一个战场. 夜风渐凉,再度穿上薄外套,企图用衣物掩盖内心的慌乱,还能再学到一点吗?后天能否遇上熟悉的知识点,恰好是现在眼前所及的?——或许也是徒劳吧.要不,让时间过的再快一点,现在就可以打开电脑,迎接最终的试炼?——那样的话,万一遇上本可以今天回顾的知识点,可就追悔莫及了. 明天

CSP2019题解

按照CSP题目顺序来写 格雷码 不难发现答案可以递归找到,然后每一次做即可. 代码 括号树 简单题,直接在树上搞一个栈然后回溯即可. 括号树nmsl 代码 树上的数 咕咕咕 Emiya 家今天的饭 很显然可以看出这题可以容斥,然后就可以写一个\(O(mn^3)\)的\(dp\). 然后考虑后面那两维状态可以做一个差,这样子就优化成了\(O(2mn^2)\),然后就可以过了. 代码 划分 \(\texttt{__int128}\)不香吗 代码 树的重心 代码 原文地址:https://www.cn

CSP2019 题解

CSP2019 题解 D1T1 格雷码(code) 题目传送门 https://loj.ac/problem/3208 题解 按照题意模拟就可以了. 对于第 \(i\) 位,如果 \(k \geq 2^i\) 那么这一位就是 \(1\),然后把 \(k\) 变成 \(2^{i + 1} - k - 1\).否则这一位为 \(0\),\(k\) 不变. 代码 https://loj.ac/submission/687508 D1T2 括号树(brackets) 题目传送门 https://loj.