HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)
最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固
在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板。
AC自动机其实就是字典树和KMP的结合,然后去思考一下KMP的原理,然后就是在字典树上实现KMP
这里最重要的思想可能就是fail的思想,就像KMP一样,匹配失败后,有一个next的数组去回溯(最长公共前缀后缀)
如何理解了KMP的话,感觉这个不会很难理解,字典树是一个非常简单的东西就不用讲了吧。
HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430
这是我总结出来的AC自动机解决的第一类问题,求文本串和模式串的关系(模式串出现几次之类的问题)
我把这几题放一起写了算了,因为套路一样随便改一下就好了
Keywords Search HDU - 2222
询问有多少个模式串出现在了文本串里面。
将模式串插入Trie树中,然后直接查询就好了。
- #include <set>
- #include <map>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <cstdio>
- #include <string>
- #include <vector>
- #include <time.h>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #include <unordered_map>
- #define pi acos(-1.0)
- #define eps 1e-9
- #define fi first
- #define se second
- #define rtl rt<<1
- #define rtr rt<<1|1
- #define bug printf("******\n")
- #define mem(a, b) memset(a,b,sizeof(a))
- #define name2str(x) #x
- #define fuck(x) cout<<#x" = "<<x<<endl
- #define sf(n) scanf("%d", &n)
- #define sff(a, b) scanf("%d %d", &a, &b)
- #define sfff(a, b, c) scanf("%d %d %d", &a, &b, &c)
- #define sffff(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
- #define pf printf
- #define FIN freopen("data.txt","r",stdin)
- #define gcd(a, b) __gcd(a,b)
- #define lowbit(x) x&-x
- #define IO iOS::sync_with_stdio(false)
- using namespace std;
- typedef long long LL;
- typedef unsigned long long ULL;
- const int maxn = 1e6 + ;
- const int maxm = 8e6 + ;
- const int INF = 0x3f3f3f3f;
- const int mod = 1e9 + ;
- struct Aho_Corasick {
- int next[][], fail[], End[];
- int root, cnt;
- int newnode() {
- for (int i = ; i < ; i++) next[cnt][i] = -;
- End[cnt++] = ;
- return cnt - ;
- }
- void init() {
- cnt = ;
- root = newnode();
- }
- void insert(char buf[]) {
- int len = strlen(buf);
- int now = root;
- for (int i = ; i < len; i++) {
- if (next[now][buf[i] - 'a'] == -) next[now][buf[i] - 'a'] = newnode();
- now = next[now][buf[i] - 'a'];
- }
- End[now]++;
- }
- void build() {
- queue<int> Q;
- fail[root] = root;
- for (int i = ; i < ; i++)
- if (next[root][i] == -) next[root][i] = root;
- else {
- fail[next[root][i]] = root;
- Q.push(next[root][i]);
- }
- while (!Q.empty()) {
- int now = Q.front();
- Q.pop();
- for (int i = ; i < ; i++)
- if (next[now][i] == -) next[now][i] = next[fail[now]][i];
- else {
- fail[next[now][i]] = next[fail[now]][i];
- Q.push(next[now][i]);
- }
- }
- }
- int query(char buf[]) {
- int len = strlen(buf);
- int now = root;
- int res = ;
- for (int i = ; i < len; i++) {
- now = next[now][buf[i] - 'a'];
- int temp = now;
- while (temp != root) {
- res += End[temp];
- End[temp] = ;
- temp = fail[temp];
- }
- }
- return res;
- }
- void debug() {
- for (int i = ; i < cnt; i++) {
- printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
- for (int j = ; j < ; j++) printf("%2d", next[i][j]);
- printf("]\n");
- }
- }
- }ac;
- char buf[];
- int T,n;
- int main() {
- sf(T);
- while(T--){
- sf(n);
- ac.init();
- for (int i = ; i < n; ++i) {
- scanf("%s",buf);
- ac.insert(buf);
- }
- scanf("%s",buf);
- ac.build();
- printf("%d\n",ac.query(buf));
- }
- return ;
- }
病毒侵袭 HDU - 2896
给出n个模式串,对m个串进行匹配,输出匹配的模式串的编号,以及总共多少个串可以匹配。
字符总数有128,而且编号要排序。
- #include <set>
- #include <map>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <cstdio>
- #include <string>
- #include <vector>
- #include <time.h>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #include <unordered_map>
- #define pi acos(-1.0)
- #define eps 1e-9
- #define fi first
- #define se second
- #define rtl rt<<1
- #define rtr rt<<1|1
- #define bug printf("******\n")
- #define mem(a, b) memset(a,b,sizeof(a))
- #define name2str(x) #x
- #define fuck(x) cout<<#x" = "<<x<<endl
- #define sf(n) scanf("%d", &n)
- #define sff(a, b) scanf("%d %d", &a, &b)
- #define sfff(a, b, c) scanf("%d %d %d", &a, &b, &c)
- #define sffff(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
- #define pf printf
- #define FIN freopen("../date.txt","r",stdin)
- #define gcd(a, b) __gcd(a,b)
- #define lowbit(x) x&-x
- #define IO iOS::sync_with_stdio(false)
- using namespace std;
- typedef long long LL;
- typedef unsigned long long ULL;
- const int maxn = 1e6 + ;
- const int maxm = 8e6 + ;
- const int INF = 0x3f3f3f3f;
- const int mod = 1e9 + ;
- struct Aho_Corasick {
- int next[][], fail[], End[],vis[];
- int root, cnt;
- vector<int>ans;
- int newnode() {
- for (int i = ; i < ; i++) next[cnt][i] = -;
- End[cnt++] = ;
- return cnt - ;
- }
- void init() {
- cnt = ;
- root = newnode();
- }
- void insert(char buf[],int id) {
- int len = strlen(buf);
- int now = root;
- for (int i = ; i < len; i++) {
- if (next[now][buf[i]] == -) next[now][buf[i]] = newnode();
- now = next[now][buf[i]];
- }
- End[now]++;
- vis[now]=id;
- }
- void build() {
- queue<int> Q;
- fail[root] = root;
- for (int i = ; i < ; i++)
- if (next[root][i] == -) next[root][i] = root;
- else {
- fail[next[root][i]] = root;
- Q.push(next[root][i]);
- }
- while (!Q.empty()) {
- int now = Q.front();
- Q.pop();
- for (int i = ; i < ; i++)
- if (next[now][i] == -) next[now][i] = next[fail[now]][i];
- else {
- fail[next[now][i]] = next[fail[now]][i];
- Q.push(next[now][i]);
- }
- }
- }
- int query(char buf[]) {
- int len = strlen(buf);
- int now = root;
- int res = ;
- for (int i = ; i < len; i++) {
- now = next[now][buf[i]];
- int temp = now;
- while (temp != root) {
- res += End[temp];
- if (vis[temp]) ans.push_back(vis[temp]);
- // End[temp] = 0;
- temp = fail[temp];
- }
- }
- return res;
- }
- void pf_ans(){
- sort(ans.begin(),ans.end());
- for (int i= ;i<ans.size() ;i++) printf(" %d",ans[i]);
- printf("\n");
- ans.clear();
- }
- void debug() {
- for (int i = ; i < cnt; i++) {
- printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
- for (int j = ; j < ; j++) printf("%2d", next[i][j]);
- printf("]\n");
- }
- }
- }ac;
- char buf[];
- int n,m;
- int main() {
- // FIN;
- while(~sf(n)){
- ac.init();
- for (int i = ; i <= n; ++i) {
- scanf("%s",buf);
- ac.insert(buf,i);
- }
- ac.build();
- sf(m);
- int tot=;
- for (int i = ; i <= m; ++i) {
- scanf("%s",buf);
- //fuck(i);
- if (ac.query(buf)) {
- tot++;
- printf("web %d:",i);
- ac.pf_ans();
- }
- }
- printf("total: %d\n",tot);
- }
- return ;
- }
病毒侵袭持续中 HDU - 3065
这题题意和上一题一样,多了一个输出出现次数。
- #include <set>
- #include <map>
- #include <stack>
- #include <queue>
- #include <cmath>
- #include <cstdio>
- #include <string>
- #include <vector>
- #include <time.h>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #include <unordered_map>
- #define pi acos(-1.0)
- #define eps 1e-9
- #define fi first
- #define se second
- #define rtl rt<<1
- #define rtr rt<<1|1
- #define bug printf("******\n")
- #define mem(a, b) memset(a,b,sizeof(a))
- #define name2str(x) #x
- #define fuck(x) cout<<#x" = "<<x<<endl
- #define sf(n) scanf("%d", &n)
- #define sff(a, b) scanf("%d %d", &a, &b)
- #define sfff(a, b, c) scanf("%d %d %d", &a, &b, &c)
- #define sffff(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
- #define pf printf
- #define FIN freopen("../date.txt","r",stdin)
- #define gcd(a, b) __gcd(a,b)
- #define lowbit(x) x&-x
- #define IO iOS::sync_with_stdio(false)
- using namespace std;
- typedef long long LL;
- typedef unsigned long long ULL;
- const int maxn = 1e6 + ;
- const int maxm = 8e6 + ;
- const int INF = 0x3f3f3f3f;
- const int mod = 1e9 + ;
- char str[][];
- char buf[];
- int n, m;
- struct Aho_Corasick {
- int next[*][], fail[*], End[*], num[];
- int root, cnt;
- int newnode() {
- for (int i = ; i < ; i++) next[cnt][i] = -;
- End[cnt++] = ;
- return cnt - ;
- }
- void init() {
- cnt = ;
- root = newnode();
- }
- void insert(char buf[], int id) {
- int len = strlen(buf);
- int now = root;
- for (int i = ; i < len; i++) {
- if (next[now][buf[i]] == -) next[now][buf[i]] = newnode();
- now = next[now][buf[i]];
- }
- End[now] = id;
- }
- void build() {
- queue<int> Q;
- fail[root] = root;
- for (int i = ; i < ; i++)
- if (next[root][i] == -) next[root][i] = root;
- else {
- fail[next[root][i]] = root;
- Q.push(next[root][i]);
- }
- while (!Q.empty()) {
- int now = Q.front();
- Q.pop();
- for (int i = ; i < ; i++)
- if (next[now][i] == -) next[now][i] = next[fail[now]][i];
- else {
- fail[next[now][i]] = next[fail[now]][i];
- Q.push(next[now][i]);
- }
- }
- }
- void query(char buf[]) {
- for(int i = ;i <= n;i++) num[i] = ;
- int len = strlen(buf);
- int now = root;
- for (int i = ; i < len; i++) {
- now = next[now][buf[i]];
- int temp = now;
- while (temp != root) {
- if (End[temp]) num[End[temp]]++;
- // End[temp] = 0;
- temp = fail[temp];
- }
- }
- for (int i= ;i<=n ;i++)
- if (num[i]) printf("%s: %d\n",str[i],num[i]);
- }
- void debug() {
- for (int i = ; i < cnt; i++) {
- printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
- for (int j = ; j < ; j++) printf("%2d", next[i][j]);
- printf("]\n");
- }
- }
- } ac;
- int main() {
- //FIN;
- while (~sf(n)) {
- ac.init();
- for (int i = ; i <= n; ++i) {
- scanf("%s", str[i]);
- ac.insert(str[i], i);
- }
- ac.build();
- scanf("%s", buf);
- ac.query(buf);
- }
- return ;
- }
Detect the Virus ZOJ - 3430
这题本质上还是和上面一个套路只是恶心了很多。
题目是给先你n组经过编码后的病毒串:
编码就是将原串转成二进制后取每6位进行转化成10进制后与上面表格对应的字符串,
末尾不足6位补0,且原串个数为3k+1则在编码后的串里增加'==',
若个数为3k+2则增加'=',给定的模式串也是编码后的串,
所以需要进行反编码然后就是赤裸裸的AC自动机模版了。
注意转化后的字符范围为256(包括转义字符),strlen也无法使用,需要用unsigned char
- #include <cstdio>
- #include <cstring>
- #include <queue>
- #define sf(n) scanf("%d", &n)
- #define sff(a, b) scanf("%d %d", &a, &b)
- using namespace std;
- typedef long long LL;
- typedef unsigned long long ULL;
- const int maxn = 1e6 + ;
- const int maxm = 8e6 + ;
- const int INF = 0x3f3f3f3f;
- const int mod = 1e9 + ;
- unsigned char buf[];
- char str[];
- unsigned char s[];
- int n, m, tot;
- struct Aho_Corasick {
- int next[ * ][], fail[ * ], End[ * ], vis[];
- int root, cnt;
- int newnode() {
- for (int i = ; i < ; i++) next[cnt][i] = -;
- End[cnt++] = ;
- return cnt - ;
- }
- void init() {
- cnt = ;
- root = newnode();
- }
- void insert(unsigned char buf[], int len, int id) {
- int now = root;
- for (int i = ; i < len; i++) {
- if (next[now][buf[i]] == -) next[now][buf[i]] = newnode();
- now = next[now][buf[i]];
- }
- End[now] = id;
- }
- void build() {
- queue<int> Q;
- fail[root] = root;
- for (int i = ; i < ; i++)
- if (next[root][i] == -) next[root][i] = root;
- else {
- fail[next[root][i]] = root;
- Q.push(next[root][i]);
- }
- while (!Q.empty()) {
- int now = Q.front();
- Q.pop();
- for (int i = ; i < ; i++)
- if (next[now][i] == -) next[now][i] = next[fail[now]][i];
- else {
- fail[next[now][i]] = next[fail[now]][i];
- Q.push(next[now][i]);
- }
- }
- }
- int query(unsigned char buf[], int len, int n) {
- memset(vis, false, sizeof(vis));
- int now = root;
- for (int i = ; i < len; i++) {
- now = next[now][buf[i]];
- int temp = now;
- while (temp != root) {
- if (End[temp] != -)
- vis[End[temp]] = true;
- temp = fail[temp];
- }
- }
- int res = ;
- for (int i = ; i <= n; i++) if (vis[i]) res++;
- return res;
- }
- void debug() {
- for (int i = ; i < cnt; i++) {
- printf("id = %3d,fail = %3d,end = %3d,chi = [", i, fail[i], End[i]);
- for (int j = ; j < ; j++) printf("%2d", next[i][j]);
- printf("]\n");
- }
- }
- } ac;
- unsigned char Get(char ch) {
- if (ch >= 'A' && ch <= 'Z')return ch - 'A';
- if (ch >= 'a' && ch <= 'z')return ch - 'a' + ;
- if (ch >= '' && ch <= '')return ch - '' + ;
- if (ch == '+')return ;
- else return ;
- }
- void change(unsigned char str[], int len) {
- int t = ;
- for (int i = ; i < len; i += ) {
- buf[t++] = ((str[i] << ) | (str[i + ] >> ));
- if (i + < len)
- buf[t++] = ((str[i + ] << ) | (str[i + ] >> ));
- if (i + < len)
- buf[t++] = ((str[i + ] << ) | str[i + ]);
- }
- tot = t;
- }
- int main() {
- while (~sf(n)) {
- ac.init();
- for (int i = ; i <= n; ++i) {
- scanf("%s", str);
- int len = strlen(str);
- while (str[len - ] == '=')len--;
- for (int j = ; j < len; j++) s[j] = Get(str[j]);
- change(s, len);
- ac.insert(buf, tot, i);
- }
- ac.build();
- sf(m);
- for (int i = ; i <= m; i++) {
- scanf("%s", str);
- int len = strlen(str);
- while (str[len - ] == '=') len--;
- for (int j = ; j < len; j++) s[j] = Get(str[j]);
- change(s, len);
- printf("%d\n", ac.query(buf, tot, n));
- }
- printf("\n");
- }
- return ;
- }
HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)的更多相关文章
- Detect the Virus ZOJ - 3430 AC自动机
One day, Nobita found that his computer is extremely slow. After several hours' work, he finally fou ...
- ZOJ - 3430 ac自动机
这题主要就是解码过程很恶心,不能用char存,一共wa了20发 题意:先给n串加密后的字符,然后m串加密后的字符,解码之后求n对应每个m的匹配数,很显然的ac自动机 加密过程是先用对应ascii表的标 ...
- hdu 3695:Computer Virus on Planet Pandora(AC自动机,入门题)
Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 256000/1280 ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵)
考研路茫茫——单词情结 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU 2846 (AC自动机+多文本匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2846 题目大意:有多个文本,多个模式串.问每个模式串中,有多少个文本?(匹配可重复) 解题思路: 传统 ...
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
http://acm.hdu.edu.cn/showproblem.php?pid=2243 题意: 给出m个模式串,求长度不超过n的且至少包含一个模式串的字符串个数. 思路: 如果做过poj2778 ...
- HDU 6138 Fleet of the Eternal Throne(AC自动机)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6138 [题目大意] 给出一些串,询问第x个串和第y个串的公共子串, 同时要求该公共子串为某个串的前 ...
- HDU 2896:病毒侵袭(AC自动机)
http://acm.hdu.edu.cn/showproblem.php?pid=2896 题意:中文题意. 思路:AC自动机模板题.主要在于字符有128种,输出还要排序和去重! 注意是“total ...
- HDU 3695 Computer Virus on Planet Pandora(AC自动机模版题)
Computer Virus on Planet Pandora Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 256000/1280 ...
随机推荐
- Jmeter-【JSON Extractor】-响应结果中三级key取值
一.请求返回样式 二.取第三个option 三.查看结果
- delphi根据不同图片生成不规则窗口的实现(仅限于BMP格式)
unit CreateImageForm; interface uses Windows, SysUtils, Variants, Classes, Graphics; procedure Creat ...
- NX二次开发-UFUN求两个对象最短距离UF_MODL_ask_minimum_dist
NX9+VS2012 #include <uf.h> #include <uf_modl.h> #include <uf_ui.h> UF_initialize() ...
- NX二次开发-UFUN结合NXOPEN开发_常用代码模板
hpp //头文件 #include <NXOpen/Part.hxx> #include <NXOpen/PartCollection.hxx> #include <N ...
- flutter 插件
flutter_spinkit loading动画
- iOS开发之UIMenuController
1.简介 用于剪切.复制.粘贴.选择.选择ALL和DELETE命令的菜单界面. UITextField.UIWebView.UITextView自带有这种UIMenuController效果: 2.相 ...
- Debian怎么配置网卡(IP)
来自:http://jingyan.baidu.com/article/a3f121e4d27a53fc9152bb65.html Debian可以配置静态IP.动态IP使Debian连上互联网.用户 ...
- 2019 USP Try-outs 练习赛
// 好久没更博客了,最近打了很多场练习赛&校内PK赛,大概自闭忙于补题吧 // 9.26 周四练习赛 A. Kolkhozy 题意 有 n 个数 \(f[i]\) ,有 q 次询问(l, r ...
- Redis连不上的一些细节配置
远程链接redis连不上,在确保防火墙设置正确的情况下 把redis.conf中的 bind 127.0.0.1注释 另外把protected-mode yes 改为protected-mode no
- 解决WIN8输入法的问题,Ctrl+空格,Ctrl+Shift,切换问题
在WIN8中,我们曾经熟悉的的Ctrl+空格和Ctrl+Shift消失了,取而导致的是WIN+空格. 在这里先简单解释一下WIN8的输入法结构: 在WIN7以前的输入法中,输入法采用了平行目录的结构, ...