• BZOJ3940: [Usaco2015 Feb]Censoring


    给个长度<=1e5的串s,再给n个模板串总长不超1e5,每次把s中起始位置最早的一个模板串删掉,求最后剩的串。

    AC自动机,开个栈记一下每次走到哪里,匹配成功后直接在栈里找到这一串的初始位置对应自动机上的节点,从而回到刚才的样子就行了。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 //#include<iostream>
     6 using namespace std;
     7 
     8 #define maxs 100011
     9 char s[maxs],p[maxs];int n,len;
    10 struct Trie
    11 {
    12     int ch[maxs][27],size;
    13     int fail[maxs],last[maxs],dep[maxs];bool val[maxs];
    14     Trie() {size=0;memset(ch[0],0,sizeof(ch[0]));dep[0]=0;}
    15     int idx(char s) {return s-'a';}
    16     void insert(char* s)
    17     {
    18         int len=strlen(s),now=0;
    19         for (int i=0;i<len;i++)
    20         {
    21             int u=idx(s[i]);
    22             if (!ch[now][u])
    23             {
    24                 size++;
    25                 memset(ch[size],0,sizeof(ch[size]));
    26                 val[size]=0;
    27                 ch[now][u]=size;
    28                 dep[size]=dep[now]+1;
    29             }
    30             now=ch[now][u];
    31         }
    32         val[now]=1;
    33     }
    34     int sta[maxs],top;char ans[maxs];
    35     void match(char* t)
    36     {
    37         int len=strlen(t),now=0;top=0;
    38         for (int i=0;i<len;i++)
    39         {
    40             int u=idx(t[i]);
    41             now=ch[now][u];
    42             sta[++top]=now;
    43             ans[top]=t[i];
    44             if (val[now])
    45             {
    46                 top-=dep[now];
    47                 now=sta[top];
    48             }
    49         }
    50     }
    51     int que[maxs],head,tail;
    52     void makefail()
    53     {
    54         head=tail=fail[0]=0;
    55         for (int i=0;i<26;i++)
    56         {
    57             int u=ch[0][i];
    58             if (u)
    59             {
    60                 fail[u]=0;
    61                 que[tail++]=u;
    62                 last[u]=0;
    63             }
    64         }
    65         while (head!=tail)
    66         {
    67             const int now=que[head++];
    68             for (int i=0;i<26;i++)
    69             {
    70                 const int u=ch[now][i];
    71                 if (!u) {ch[now][i]=ch[fail[now]][i];continue;}
    72                 que[tail++]=u;
    73                 fail[u]=ch[fail[now]][i];
    74                 last[u]=val[fail[now]]?fail[now]:last[fail[now]];
    75             }
    76         }
    77     }
    78 }t;
    79 int main()
    80 {
    81     scanf("%s",s);
    82     scanf("%d",&n);
    83     for (int i=1;i<=n;i++)
    84     {
    85         scanf("%s",p);
    86         t.insert(p);
    87     }
    88     t.makefail();
    89     t.match(s);
    90     t.ans[t.top+1]='';
    91     puts(t.ans+1);
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    字符串型
    字符型
    实型(浮点型)
    sizeof
    数据类型
    标识符
    Win32汇编
    Win32汇编
    C# 语言程序设计笔记
    鬼泣4:寻找无限生命/剑气/暴怒
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7471432.html
Copyright © 2020-2023  润新知