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]='\0';
91     puts(t.ans+1);
92     return 0;
93 }
View Code

 

转载于:https://www.cnblogs.com/Blue233333/p/7471432.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值