码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 10679 I Love Strings

时间:2016-08-29 06:55:12      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:

传送门

题目大意

给定文本串$S$和若干模式串$\{T\}$, 对每个模式串$T$, 询问$T$是否为$S$的字串.

Solution

裸的AC自动机, 也可以用后缀数组做.

P.S. 这题数据很弱, 朴素的字符串匹配也能过.

Pitfalls

模式串有重复的. 这样, 在建TRIE时就不能直接对每个模式串对应的节点 (尾节点) 标记上模式串的序号, 否则对于重复出现的模式串, 最后一次出现的那个会把在它之前的那些覆盖掉.

正确的做法是, 对于每个尾节点作唯一标号. 另外维护一个表$idx[]$, $idx[i]$表示第$i$个模式串的尾节点的标号.

另外要注意AC自动机的某些易错的实现细节, 代码注释有提及.

Implementation

注释比较详细, 可作为模板.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N{1<<20}, M{1<<10};
 5 
 6 bool res[M];
 7 int idx[M];
 8 char s[N], t[M];
 9 int ch[N][52], id[N], fail[N], last[N];
10 
11 
12 int get_id(char ch){
13     return islower(ch)?ch-a:ch-A+26;
14 }
15 
16 queue<int> que;
17 
18 int main(){
19     // cout<<int(‘a‘)<<‘ ‘<<int(‘z‘)<<‘ ‘<<int(‘A‘)<<‘ ‘<<int(‘Z‘)<<endl;
20     int T;
21     for(cin>>T; T--; ){
22         int q;
23         scanf("%s%d", s, &q);
24         int tail=0;
25 
26         memset(res, false, sizeof(res));    //error-prone
27 
28         memset(ch[tail], 0, sizeof(ch[tail]));
29         tail++;
30 
31         for(int i=1; i<=q; i++){
32             scanf("%s", t);
33             int u=0;
34             for(int j=0; t[j]; j++){
35                 int &v=ch[u][get_id(t[j])];
36                 if(!v){
37                     v=tail++;
38                     memset(ch[v], 0, sizeof(ch[v]));
39                     id[v]=0;
40                 }
41                 u=v;
42             }
43             if(!id[u]) id[u]=i; //error-prone: possibly duplicate patterns
44             idx[i]=id[u];
45         }
46 
47         for(int i=0; i<52; i++){
48             int u=ch[0][i];
49             if(u){
50                 que.push(u);
51                 fail[u]=last[u]=0;  //error-prone, must be initialized!!
52             }
53         }
54 
55         for(; que.size(); ){
56             int u=que.front();
57             que.pop();
58             for(int i=0; i<52; i++){
59                 //!view a variable (object) as an entity
60                 int &v=ch[u][i];
61                 if(v){  //v is a new node, construct a new node of AC automata
62                     que.push(v);
63                     //no need to init. last[] and fail[], as they are is induced.
64                     fail[v]=ch[fail[u]][i];
65                     last[v]=id[fail[v]]?fail[v]:last[fail[v]];
66                 }
67                 else{   //the expected node v does not exist
68                     v=ch[fail[u]][i];
69                 }
70             }
71         }
72 
73         for(int i=0, u=0; s[i]; i++){
74             u=ch[u][get_id(s[i])];
75             res[id[u]]=true;
76             for(int v=last[u]; v; res[id[v]]=true, v=last[v]);  //error-prone
77         }
78 
79         for(int i=1; i<=q; i++)
80             puts(res[idx[i]]?"y":"n");
81         
82     }
83 }

 


上穷碧落下黄泉.

 

UVA 10679 I Love Strings

标签:

原文地址:http://www.cnblogs.com/Patt/p/5816531.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!