当前位置: 首页 > news >正文

模板汇总——AC自动机

 

AC自动机 模板题 HDU-2222 Keywords Search

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define LL long long
  4 #define ULL unsigned LL
  5 #define fi first
  6 #define se second
  7 #define lson l,m,rt<<1
  8 #define rson m+1,r,rt<<1|1
  9 #define max3(a,b,c) max(a,max(b,c))
 10 #define min3(a,b,c) min(a,min(b,c))
 11 const int INF = 0x3f3f3f3f;
 12 const LL mod = 1e9+7;
 13 typedef pair<int,int> pll;
 14 const int N = 1e5+10, M = 1e3;
 15 char str[N*10];
 16 int trie[N*10][26];
 17 int fair[N*26];
 18 int cnt[N*26];
 19 int tot = 2;
 20 void Insert(){
 21     int rt = 1, len = strlen(str);
 22     for(int i = 0; i < len; i++){
 23         int id = str[i] - 'a';
 24         if(trie[rt][id] == 0){
 25             cnt[tot] = 0;
 26             fair[tot] = 0;
 27             trie[rt][id] = tot++;
 28         }
 29         rt = trie[rt][id];
 30     }
 31     cnt[rt]++;
 32 }
 33 void Build_tree(){
 34     queue<int> q;
 35     q.push(1);
 36     int p;
 37     while(!q.empty()){
 38         int tmp = q.front();
 39         q.pop();
 40         for(int i = 0; i < 26; i++){
 41             if(trie[tmp][i] != 0){
 42                 if(tmp == 1)
 43                     fair[trie[tmp][i]] = 1;
 44                 else{
 45                     p = fair[tmp];
 46                     while(p){
 47                         if(trie[p][i]){
 48                             fair[trie[tmp][i]] = trie[p][i];
 49                             break;
 50                         }
 51                         else p = fair[p];
 52                     }
 53                     if(!p)  fair[trie[tmp][i]] = 1;
 54                 }
 55                 q.push(trie[tmp][i]);
 56             }
 57         }
 58     }
 59 }
 60 int Query(){
 61     int rt = 1, ret = 0, len = strlen(str);
 62     for(int i = 0; i < len; i++){
 63         int id = str[i] - 'a';
 64         while(!trie[rt][id] && rt != 1) rt = fair[rt];
 65         rt = trie[rt][id];
 66         if(rt == 0) rt = 1;
 67         int tmp = rt;
 68         while(tmp != 1){
 69             if(cnt[tmp] >= 0){
 70                 ret += cnt[tmp];
 71                 cnt[tmp] = -1;
 72             }
 73             else break;
 74             tmp = fair[tmp];
 75         }
 76     }
 77     return ret;
 78 }
 79 void init(){
 80     for(int i = 1; i < tot; i++){
 81         for(int j = 0; j < 26; j++)
 82             trie[i][j] = 0;
 83     }
 84     tot = 2; 
 85 }
 86 int main(){
 87     int T;
 88     scanf("%d", &T);
 89     while(T--){
 90         init();
 91         int n;
 92         scanf("%d", &n);
 93         while(n--){
 94             scanf("%s", str);
 95             Insert();
 96         }
 97         Build_tree();
 98         scanf("%s", str);
 99         printf("%d\n", Query());
100     }
101     return 0;
102 }
View Code

 

 

2进制分组AC自动机

String Set Queries

假如给你21个串: 分为 16+4+1,再添加一个串的时候,即21+1, 22 = 16+4+1+1 = 16 + 4 + 2。 这样每次加串之后只会有logn个操作,查询也变成logn操作, 对于同一个串建立fair指针的次数就少了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
 4 #define LL long long
 5 #define ULL unsigned LL
 6 #define fi first
 7 #define se second
 8 #define pb push_back
 9 #define lson l,m,rt<<1
10 #define rson m+1,r,rt<<1|1
11 #define max3(a,b,c) max(a,max(b,c))
12 #define min3(a,b,c) min(a,min(b,c))
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const LL mod =  (int)1e9+7;
16 const int N = 3e5 + 100;
17 struct Node{
18     static const int m = 26;static const int KN = N;
19     int next[KN][m], fair[KN], tot = 0, mark[KN], mark1[KN], root[20], cnt = 0, si[20];
20     void Build(int x){
21         queue<int> q;
22         q.push(x);
23         int pos, p, v;
24         while(!q.empty()){
25             pos = q.front(), q.pop();
26             for(int i = 0; i < m; i++){
27                 if(!next[pos][i]) continue;
28                 p = fair[pos]; v = next[pos][i];
29                 while(p && !next[p][i]) p = fair[p];
30                 if(p) fair[v] = next[p][i];
31                 else fair[v] = x;
32                 q.push(v);
33                 mark1[v] = mark1[fair[v]] + mark[v];
34             }
35         }
36     }
37     void Add(char s[], char ch){
38         root[++cnt] = ++tot; si[cnt] = 1;
39         int pos = root[cnt];
40         for(int i = 0; s[i]; i++){
41             if(!next[pos][s[i]-ch]) next[pos][s[i]-ch] = ++tot;
42             pos = next[pos][s[i]-ch];
43         }
44         mark[pos]++;
45         while(si[cnt] == si[cnt-1]){
46             Unit(root[cnt-1], root[cnt]);
47             si[--cnt] *= 2;
48         }
49         Build(root[cnt]);
50     }
51     int Query(char s[], char ch){
52         int pos, ret = 0;
53         for(int id = 1; id <= cnt; id++){
54             pos = root[id];
55             for(int i = 0; s[i]; i++){
56                 while(pos && !next[pos][s[i]-ch]) pos = fair[pos];
57                 if(pos) pos = next[pos][s[i]-ch];
58                 else pos = root[id];
59                 ret += mark1[pos];
60             }
61         }
62         return ret;
63     }
64     void Unit(int u, int v){
65         mark[u] += mark[v];
66         for(int i = 0; i < m; i++){
67             if(!next[u][i] || !next[v][i]) next[u][i] += next[v][i];
68             else Unit(next[u][i], next[v][i]);
69         }
70     }
71 }ac[2];
72 char str[N];
73 int main(){
74     int n, k;
75     scanf("%d", &n);
76     while(n--){
77         scanf("%d%s", &k, str);
78         if(k <= 2) ac[k-1].Add(str, 'a');
79         else {
80             printf("%d\n", ac[0].Query(str, 'a')-ac[1].Query(str, 'a'));
81             fflush(stdout);
82         }
83     }
84     return 0;
85 }
86 
87 AC自动机
View Code

 

转载于:https://www.cnblogs.com/MingSD/p/9524901.html

相关文章:

  • vue keep-alive组件
  • SQL Server CONVERT() 函数
  • JS一元操作符递增与递减
  • VUE - eslint - 笔记
  • jQuery文档操作之插入操作
  • SQL Server 导入excel时“该值违反了该列的完整性约束”错误
  • 使用一个公网地址配置多个Horizon安全服务器与连接服务器的方法
  • 为数据赋予超能力,阿里云重磅推出Serverless数据分析引擎-Data Lake Analyti
  • android 自定义view
  • 自己手撸一个符合Promise/A+的Promise
  • Zookeeper分布式集群原理与功能
  • 体积减少80%!释放webpack tree-shaking的真正潜力
  • CentOS7上Docker安装与卸载
  • webpack4.0各个击破(9)—— karma篇
  • day62:mysql主从配置
  • 08.Android之View事件问题
  • Akka系列(七):Actor持久化之Akka persistence
  • Android 架构优化~MVP 架构改造
  • FineReport中如何实现自动滚屏效果
  • Intervention/image 图片处理扩展包的安装和使用
  • js对象的深浅拷贝
  • React中的“虫洞”——Context
  • springboot_database项目介绍
  • SpringBoot几种定时任务的实现方式
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • vuex 笔记整理
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 坑!为什么View.startAnimation不起作用?
  • 我有几个粽子,和一个故事
  • k8s使用glusterfs实现动态持久化存储
  • Nginx实现动静分离
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • # 数论-逆元
  • #define用法
  • #图像处理
  • $$$$GB2312-80区位编码表$$$$
  • (12)Linux 常见的三种进程状态
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (九)c52学习之旅-定时器
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转载)hibernate缓存
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • .mat 文件的加载与创建 矩阵变图像? ∈ Matlab 使用笔记
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .Net 代码性能 - (1)
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .Net6 Api Swagger配置
  • .netcore 获取appsettings
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • /bin/bash^M: bad interpreter: No such file ordirectory
  • [1181]linux两台服务器之间传输文件和文件夹