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;
这样就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }