zoukankan      html  css  js  c++  java
  • 【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
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    C++实现数字媒体三维图像渲染
    C++实现数字媒体三维图像变换
    C++实现数字媒体二维图像变换
    C++实现glut绘制点、直线、多边形、圆
    语音识别之梅尔频谱倒数MFCC(Mel Frequency Cepstrum Coefficient)
    Java中的BigDecimal类精度问题
    spring 手册
    bootstrap 参考文档
    springBoot入门文章
    JNDI
  • 原文地址:https://www.cnblogs.com/horizonwd/p/12051481.html
Copyright © 2011-2022 走看看