hdu5880 (AC自动机)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu5880 (AC自动机)相关的知识,希望对你有一定的参考价值。

题目链接:hdu5880 Family View

题意:敏感词屏蔽,给一堆敏感词,给一段文本,要求把文本中所有的敏感词用*代替。

题解:对敏感词建出AC自动机,在AC自动机上跑文本,就可以得到文本的每个前缀的最长匹配后缀,扫一遍即可得到结果。

弱弱的说我还不会用AC自动机啊,赛后补题先留下大神的模板吧。。。

再留个博客改天练练:http://www.cnblogs.com/kuangbin/p/3164106.html

 

技术分享
  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<queue>
  6 #define CLR(a,b) memset((a),(b),sizeof((a)))
  7 using namespace std;
  8 const int N = 1000010;
  9 int d[N];
 10 int ans[N];
 11 struct Trie{
 12     int next[N][26],fail[N],end[N];
 13     int root,L;
 14     int newnode(){
 15         for(int i = 0;i < 26;i++)
 16             next[L][i] = -1;
 17         end[L++] = 0;
 18         return L-1;
 19     }
 20     void init(){
 21         L = 0;
 22         root = newnode();
 23     }
 24     void insert(char buf[]){
 25         int len = strlen(buf);
 26         int now = root;
 27         for(int i = 0;i < len;i++){
 28             if(next[now][buf[i]-a] == -1)
 29                 next[now][buf[i]-a] = newnode();
 30             now = next[now][buf[i]-a];
 31         }
 32         end[now] = 1;
 33         d[now] = len;
 34     }
 35     void build(){
 36         queue<int>Q;
 37         fail[root] = root;
 38         for(int i = 0;i < 26;i++)
 39             if(next[root][i] == -1)
 40                 next[root][i] = root;
 41             else{
 42                 fail[next[root][i]] = root;
 43                 Q.push(next[root][i]);
 44             }
 45         while( !Q.empty() ){
 46             int now = Q.front(); Q.pop();
 47             for(int i = 0;i < 26;i++)
 48                 if(next[now][i] == -1)
 49                     next[now][i] = next[fail[now]][i];
 50                 else{
 51                     fail[next[now][i]] = next[fail[now]][i];
 52                     Q.push(next[now][i]);
 53                 }
 54         }
 55     }
 56     void solve(char buf[]){
 57         int cur = root;
 58         int len = strlen(buf);
 59         int index;
 60         for(int i = 0; i < len ; ++i){
 61             if(buf[i] >= A && buf[i] <= Z)
 62                 index = buf[i] - A;
 63             else if(buf[i] >= a && buf[i] <= z)
 64                 index = buf[i] - a;
 65             else continue;
 66             cur = next[cur][index];
 67             int x = cur;
 68             while(x != root){
 69                 if(end[x]){
 70                     ans[i + 1] -= 1;
 71                     ans[i - d[x] + 1] += 1;
 72                     break;
 73                 }
 74                 x = fail[x];
 75             }
 76         }
 77     }
 78 };
 79 char buf[N];
 80 Trie ac;
 81 int main(){
 82     int T, i, n, len;
 83     scanf("%d", &T);
 84     while( T-- ){
 85         scanf("%d", &n);
 86         ac.init();
 87         for(int i = 0;i < n;i++){
 88             scanf("%s", buf);
 89             ac.insert(buf);
 90         }
 91         getchar();
 92         ac.build();
 93         gets(buf);
 94         //scanf("%s", buf);
 95         CLR(ans, 0);
 96         ac.solve(buf);
 97         long long res = 0;
 98         len = strlen(buf);
 99         for(i = 0; i < len; ++i){
100             res += ans[i];
101             if(res <= 0)
102                 printf("%c", buf[i]);
103             else printf("*");
104         }
105         puts("");
106     }
107     return 0;
108 }
View Code

 

以上是关于hdu5880 (AC自动机)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5880 Family View (AC自动机)

HDU 5880 Family View (AC自动机)

HDU5880 Family View(AC自动机)

HDU 5880 Family View

HDU3247 Resource Archiver(AC自动机+BFS+DP)

HDU4057 Rescue the Rabbit(AC自动机+状压DP)