• 洛谷 P5658 括号树(DFS)


    题目链接:https://www.luogu.com.cn/problem/P5658

    通过数据范围可以发现,这个题的复杂度要控制在O(n)~O(nlogn)之间。

    所以对于每一次处理,需要O(logn),甚至O(1)。对于O(1)的处理,可以直接想一下找规律:

    如果一个右括号能匹配左括号,且左括号的前一个括号是一个已经匹配了的右括号,那么就可以将这两个序列合并,当前右括号的贡献等于前一个右括号的贡献加一。如果没有这种情况的话,那么贡献肯定是从1开始的(只于前面的那个左括号有贡献,前面的都会被左括号的前一个所断绝)。

    注意回溯。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<stack>
     5 using namespace std;
     6 typedef long long ll;
     7 const int N=500005;
     8 int n;
     9 int head[N],fa[N],tot;
    10 char c[N];
    11 ll lst[N],ans,sum[N];
    12 stack<int> st;
    13 struct node{
    14     int to,next;
    15 }edge[N];
    16 void add(int u,int v){
    17     edge[tot].to=v;
    18     edge[tot].next=head[u];
    19     head[u]=tot++;
    20 }
    21 void DFS(int u){
    22     int t=0;
    23     if(c[u]==')'){
    24         if(!st.empty()){
    25             t=st.top();
    26             lst[u]=lst[fa[t]]+1;//可以的话,加上原来的贡献,否则贡献就从1开始 
    27             st.pop();//直接删去 
    28         }
    29     }
    30     else if(c[u]=='(') st.push(u);
    31     sum[u]=sum[fa[u]]+lst[u];
    32     for(int i=head[u];i!=-1;i=edge[i].next){
    33         int v=edge[i].to;
    34         DFS(v);
    35     }
    36     if(t!=0) st.push(t); 
    37     else if(!st.empty()) st.pop();
    38 }
    39 int main(){
    40     memset(head,-1,sizeof(head));
    41     scanf("%d",&n);
    42     scanf("%s",c+1);
    43     for(int i=1;i<n;i++){
    44         int u;
    45         scanf("%d",&u);
    46         add(u,i+1);
    47         fa[i+1]=u;
    48     }
    49     DFS(1);
    50     for(int i=1;i<=n;i++) ans^=sum[i]*(ll)i;
    51     printf("%lld
    ",ans);
    52     return 0;
    53 }
    AC代码
  • 相关阅读:
    字符串转换整数 (atoi)
    Z 字形变换
    最长回文子串
    寻找两个有序数组的中位数
    二维码QRCode
    多个线程访问url
    store procedure 翻页
    store procedure example
    使用graphics2D给图片上画字符
    procedure的over(partition by ) function
  • 原文地址:https://www.cnblogs.com/New-ljx/p/13736790.html
Copyright © 2020-2023  润新知