博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Searching the String ZOJ - 3228 AC自动机查询升级版
阅读量:5030 次
发布时间:2019-06-12

本文共 2290 字,大约阅读时间需要 7 分钟。

题意:

先给你一个不超过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 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
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" = "<
<
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

 

转载于:https://www.cnblogs.com/qldabiaoge/p/11379387.html

你可能感兴趣的文章
Android中获取应用程序(包)的大小-----PackageManager的使用(二)
查看>>
Codeforces Gym 100513M M. Variable Shadowing 暴力
查看>>
浅谈 Mybatis中的 ${ } 和 #{ }的区别
查看>>
CNN 笔记
查看>>
版本更新
查看>>
SQL 单引号转义
查看>>
start
查看>>
实现手机扫描二维码页面登录,类似web微信-第三篇,手机客户端
查看>>
PHP socket客户端长连接
查看>>
7、shell函数
查看>>
【转】Apache Jmeter发送post请求
查看>>
Nginx 基本 安装..
查看>>
【凸优化】保留凸性的几个方式(交集、仿射变换、投影、线性分式变换)
查看>>
NYOJ-613//HDU-1176-免费馅饼,数字三角形的兄弟~~
查看>>
TFS --- GrantBackup Plan Permissions Error
查看>>
傅里叶级数与积分方程
查看>>
软工作业3:用户体验分析——以“南通大学教务管理系统微信公众号”为例
查看>>
Css:背景色透明,内容不透明之终极方法!兼容所有浏览器
查看>>
我们前端跟后端是怎么合作的
查看>>
mysql存储过程
查看>>