码迷,mamicode.com
首页 > 其他好文 > 详细

CSP2019 括号树

时间:2020-02-06 10:30:26      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:pre   char   tac   异或   amp   需要   位置   lld   goto   

Description:

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

Solution:

闻到一股深深的 stack 气息。

懒得写了

Code:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;

const int N = 5e5+1;
int n;
char s[N];
int fa[N],st[N],top;
ll sum[N],ans[N];
ll fin;

struct edge
{
    int nxt;
    int to;
}e[N];
int h[N],cnt;

void add(int u,int v)
{
    e[++cnt].nxt=h[u];
    e[cnt].to=v;
    h[u]=cnt;
}

void dfs(int u)
{
    int flag=0;
    if(s[u]==')')
    {
        if(!top) goto here;
        flag=st[top];
        --top;
        sum[u]=sum[fa[flag]]+1;
    }
    else if(s[u]=='(')
    {
        st[++top]=u;
    }
    here:;
    ans[u]=ans[fa[u]]+sum[u];
    for(int i=h[u];i;i=e[i].nxt)
        dfs(e[i].to);
    if(flag) st[++top]=flag;
    else if(top) --top;
}

signed main()
{
    scanf("%d",&n);
    scanf("%s",s+1);
    for(int i=2;i<=n;++i)
    {
        scanf("%d",&fa[i]);
        add(fa[i],i);
    }
    dfs(1);
    for(int i=1;i<=n;++i)
    {
        fin^=ans[i]*ll(i);
    }
    printf("%lld",fin);
    return 0;
}

CSP2019 括号树

标签:pre   char   tac   异或   amp   需要   位置   lld   goto   

原文地址:https://www.cnblogs.com/oierwyh/p/12267566.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!