Searching the String ZOJ - 3228 AC自动机查询升级版

Posted qldabiaoge

tags:

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

题意:
先给你一个不超过1000000长度的大串s;接下来输入一个n代表接下来输入的小串个数,小串长度不超过6。
小串分两种类型0和1类型。
0类型表示小串在大串中的最大匹配个数就是常规的AC自动机的做法。
1类型表示小串在大串中不能重合的最大匹配数。
依次输出结果.(所有的串只包含小写字母)
按样例输出,注意每组测试数据后有一个换行。

题意我不想写了抄的,抄这里的 (不好意思啦)

 

0 类型的就是最开始的模板题

1 类型的处理方式就是,在建立字典树的时候弄一个dep数组,记录每一个节点的深度

然后在query的过程中查询上一个单词最后一个字母出现的位置。

if (i - last[temp] >= dep[temp]) ans[temp][1]++, last[temp] = i;

这样就可以了。

 

技术图片
  1 #include <set>
  2 #include <map>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstring>
 11 #include <iostream>
 12 #include <algorithm>
 13 
 14 #define  pi    acos(-1.0)
 15 #define  eps   1e-9
 16 #define  fi    first
 17 #define  se    second
 18 #define  rtl   rt<<1
 19 #define  rtr   rt<<1|1
 20 #define  bug                printf("******\n")
 21 #define  mem(a, b)          memset(a,b,sizeof(a))
 22 #define  name2str(x)        #x
 23 #define  fuck(x)            cout<<#x" = "<<x<<endl
 24 #define  sfi(a)             scanf("%d", &a)
 25 #define  sffi(a, b)         scanf("%d %d", &a, &b)
 26 #define  sfffi(a, b, c)     scanf("%d %d %d", &a, &b, &c)
 27 #define  sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
 28 #define  sfL(a)             scanf("%lld", &a)
 29 #define  sffL(a, b)         scanf("%lld %lld", &a, &b)
 30 #define  sfffL(a, b, c)     scanf("%lld %lld %lld", &a, &b, &c)
 31 #define  sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d)
 32 #define  sfs(a)             scanf("%s", a)
 33 #define  sffs(a, b)         scanf("%s %s", a, b)
 34 #define  sfffs(a, b, c)     scanf("%s %s %s", a, b, c)
 35 #define  sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d)
 36 #define  FIN                freopen("../date.txt","r",stdin)
 37 #define  gcd(a, b)          __gcd(a,b)
 38 #define  lowbit(x)          x&-x
 39 #define  IO                 iOS::sync_with_stdio(false)
 40 
 41 
 42 using namespace std;
 43 typedef long long LL;
 44 typedef unsigned long long ULL;
 45 const ULL seed = 13331;
 46 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
 47 const int maxn = 1e5 + 7;
 48 const int maxm = 8e6 + 10;
 49 const int INF = 0x3f3f3f3f;
 50 const int mod = 1e9 + 7;
 51 
 52 int n, vis[maxn], last[6*maxn], ans[6*maxn][2], pos[maxn], dep[6*maxn];
 53 char buf[maxn], str[maxn][10];
 54 
 55 struct Aho_Corasick 
 56     int next[1000010][26], fail[1000010], End[1000010];
 57     int root, cnt;
 58 
 59     int newnode() 
 60         for (int i = 0; i < 26; i++) next[cnt][i] = -1;
 61         End[cnt++] = 0;
 62         return cnt - 1;
 63     
 64 
 65     void init() 
 66         cnt = 0;
 67         root = newnode();
 68         dep[root]=0;
 69     
 70 
 71     int insert(char buf[]) 
 72         int len = strlen(buf);
 73         int now = root;
 74         for (int i = 0; i < len; i++) 
 75             if (next[now][buf[i] - a] == -1) 
 76                 next[now][buf[i] - a] = newnode();
 77                 dep[next[now][buf[i] - a]] = i + 1;
 78             
 79             now = next[now][buf[i] - a];
 80         
 81         End[now] = 1;
 82         return now;
 83     
 84 
 85     void build() 
 86         queue<int> Q;
 87         fail[root] = root;
 88         for (int i = 0; i < 26; i++)
 89             if (next[root][i] == -1) next[root][i] = root;
 90             else 
 91                 fail[next[root][i]] = root;
 92                 Q.push(next[root][i]);
 93             
 94         while (!Q.empty()) 
 95             int now = Q.front();
 96             Q.pop();
 97             for (int i = 0; i < 26; i++)
 98                 if (next[now][i] == -1) next[now][i] = next[fail[now]][i];
 99                 else 
100                     fail[next[now][i]] = next[fail[now]][i];
101                     Q.push(next[now][i]);
102                 
103         
104     
105 
106     void query(char buf[]) 
107         int len = strlen(buf);
108         int now = root;
109         mem(ans,0);
110         mem(last, -1);
111         for (int i = 0; i < len; i++) 
112             now = next[now][buf[i] - a];
113             int temp = now;
114             while (temp != root) 
115                 ans[temp][0]++;
116                 if (i - last[temp] >= dep[temp]) ans[temp][1]++, last[temp] = i;
117                 temp = fail[temp];
118             
119         
120     
121 
122     void debug() 
123         for (int i = 0; i < cnt; i++) 
124             printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
125             for (int j = 0; j < 26; j++) printf("%2d", next[i][j]);
126             printf("]\n");
127         
128     
129  ac;
130 
131 int main() 
132   //  FIN;
133     int cas = 1;
134     while (~sfs(buf)) 
135         ac.init();
136         sfi(n);
137         for (int i = 0; i < n; ++i) 
138             scanf("%d%s", &vis[i], str[i]);
139             pos[i] = ac.insert(str[i]);
140         
141         ac.build();
142         ac.query(buf);
143         printf("Case %d\n", cas++);
144         for (int i = 0; i < n; ++i) printf("%d\n", ans[pos[i]][vis[i]]);
145         printf("\n");
146     
147     return 0;
148 
View Code

 

以上是关于Searching the String ZOJ - 3228 AC自动机查询升级版的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ3228 Searching the String(AC自动机)

ZOJ 3228 Searching the String (AC自己主动机)

ZOJ Searching the String(match指针暴力跳fail)

Searching the String ZOJ - 3228 AC自动机查询升级版

AC自动机---Searching the String

D - Searching the String (AC自动机)