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 }