zoukankan      html  css  js  c++  java
  • BZOJ3756: Pty的字符串

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3756

    3756: Pty的字符串

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 152  Solved: 42
    [Submit][Status][Discuss]

    Description

    在神秘的东方有一棵奇葩的树,它有一个固定的根节点(编号为1)。树的每条边上都是一个字符,字符为a,b,c中的一个,你可以从树上的任意一个点出发,然后沿着远离根的边往下行走,在任意一个节点停止,将你经过的边的字符依次写下来,就能得到一个字符串,例如:
     
    在这棵树中我们能够得到的字符串是:
    c, cb, ca, a, b, a
    现在pty得到了一棵树和一个字符串S。如果S的一个子串[l,r]和树上某条路径所得到的字符串完全相同,则我们称这个子串和该路径匹配。现在pty想知道,S的所有子串和树上的所有路径的匹配总数是多少?

    Input

    第一行:n
    接下来n-1行,每行一个整数fa, 一个字符c,字符和整数之间用一个空格隔开
    第i行fa代表第i号节点的父亲,c表示第i号节点和fa的连边的字符
    最后一行为字符串S

    Output

    输出共一行,表示匹配总数

    Sample Input

    5
    1 c
    2 b
    1 a
    2 a
    cba

    Sample Output

    5
    【样例说明】
    单个字符匹配的对数为4对,两个字符匹配的对数为1对:cb

    HINT

    【数据规模】

    N<=800000 树的最大深度<=800000
    把trie树建成后缀自动机,dp一下,把s串在后缀自动机匹配的同时更新答案就好了。注意开longlong。
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #define inf 1<<30
     5 #define maxn 800005
     6 using namespace std;
     7 int n,m,head,tail,tot,last,par[maxn*2],go[maxn*2][3],val[maxn*2],size[maxn*2],q[maxn*2],d[maxn*2],fin[maxn];
     8 long long f[maxn*2],ans;
     9 char s[maxn*10];
    10 int newnode(int x){val[++tot]=val[x]+1;return tot;}
    11 void extend(int x){
    12     int p=last,np=newnode(p); size[np]=1;
    13     while(p&&!go[p][x]) go[p][x]=np,p=par[p];
    14     if(!p) par[np]=1;
    15     else{
    16         int q=go[p][x];
    17         if(val[q]==val[p]+1) par[np]=q;
    18         else{
    19             int nq=newnode(p);
    20             memcpy(go[nq],go[q],sizeof(go[q]));
    21             par[nq]=par[q]; par[q]=par[np]=nq;
    22             while(p&&go[p][x]==q) go[p][x]=nq,p=par[p];
    23         }
    24     }
    25     last=np;
    26 }
    27 int main(){
    28     scanf("%d",&n);
    29     int x; char y;
    30     last=tot=fin[1]=1;
    31     for(int i=2;i<=n;i++){
    32         scanf("%d",&x); for(y=getchar();y==' ';y=getchar());
    33         last=fin[x]; extend(y-'a'); fin[i]=last;
    34     }
    35     for(int i=1;i<=tot;i++) d[par[i]]++;
    36     for(int i=1;i<=tot;i++) if(d[i]==0) q[++tail]=i;
    37     while(head<tail){
    38         x=q[++head];
    39         size[par[x]]+=size[x];
    40         if((--d[par[x]])==0) q[++tail]=par[x];
    41     }
    42     for(int i=1;i<=tail;i++) f[i]=1LL*(val[i]-val[par[i]])*size[i];
    43     for(int i=tail;i;i--) f[q[i]]+=f[par[q[i]]];
    44     scanf("%s",s); m=strlen(s);
    45     for(int i=0,z=1,pp=0;i<m;i++){
    46         int w=s[i]-'a';
    47         while(z&&!go[z][w]) z=par[z],pp=val[z];
    48         if(!z) z=1,pp=0;
    49         else pp++,z=go[z][w],ans+=f[par[z]]+1LL*(pp-val[par[z]])*size[z];
    50     }
    51     printf("%lld
    ",ans);
    52     return 0;
    53 }
    View Code
  • 相关阅读:
    实验三-并发程序 20175201张驰
    20175201 20175215 20175229 实验二 固件程序设计
    20175201 20175215 20175229 实验一 开发环境的熟悉
    #20175201 实验五 网络编程与安全
    云班课选做
    2019-2020-12 20175313 20175328 20175329 实验五 通讯协议设计
    2019-2020-1 20175313 20175328 20175329 实验四 外设驱动程序设计
    2019-2020-1 20175313 20175328 20175329 实验三 并发程序
    20175329&20175313&20175318 2019-2020 《信息安全系统设计基础》实验三
    20175329&20175313&20175318 2019-2020 《信息安全系统设计基础》实验二
  • 原文地址:https://www.cnblogs.com/longshengblog/p/5555266.html
Copyright © 2011-2022 走看看