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
以上是关于Searching the String ZOJ - 3228 AC自动机查询升级版的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ3228 Searching the String(AC自动机)
ZOJ 3228 Searching the String (AC自己主动机)
ZOJ Searching the String(match指针暴力跳fail)