String Set Queries

题意:给你3种操作,1、加入一个串到集合中。 2、删除集合中的某一个串 3、查询集合中的字符串在给定的字符串种出现几次。(同一个串可重复)

解法:建立多个AC自动机,用二进制分组来处理。

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

代码:

 #include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const LL mod = (int)1e9+;
const int N = 3e5 + ;
struct Node{
static const int m = ;static const int KN = N;
int next[KN][m], fair[KN], tot = , mark[KN], mark1[KN], root[], cnt = , si[];
void Build(int x){
queue<int> q;
q.push(x);
int pos, p, v;
while(!q.empty()){
pos = q.front(), q.pop();
for(int i = ; i < m; i++){
if(!next[pos][i]) continue;
p = fair[pos]; v = next[pos][i];
while(p && !next[p][i]) p = fair[p];
if(p) fair[v] = next[p][i];
else fair[v] = x;
q.push(v);
mark1[v] = mark1[fair[v]] + mark[v];
}
}
}
void Add(char s[], char ch){
root[++cnt] = ++tot; si[cnt] = ;
int pos = root[cnt];
for(int i = ; s[i]; i++){
if(!next[pos][s[i]-ch]) next[pos][s[i]-ch] = ++tot;
pos = next[pos][s[i]-ch];
}
mark[pos]++;
while(si[cnt] == si[cnt-]){
Unit(root[cnt-], root[cnt]);
si[--cnt] *= ;
}
Build(root[cnt]);
}
int Query(char s[], char ch){
int pos, ret = ;
for(int id = ; id <= cnt; id++){
pos = root[id];
for(int i = ; s[i]; i++){
while(pos && !next[pos][s[i]-ch]) pos = fair[pos];
if(pos) pos = next[pos][s[i]-ch];
else pos = root[id];
ret += mark1[pos];
}
}
return ret;
}
void Unit(int u, int v){
mark[u] += mark[v];
for(int i = ; i < m; i++){
if(!next[u][i] || !next[v][i]) next[u][i] += next[v][i];
else Unit(next[u][i], next[v][i]);
}
}
}ac[];
char str[N];
int main(){
int n, k;
scanf("%d", &n);
while(n--){
scanf("%d%s", &k, str);
if(k <= ) ac[k-].Add(str, 'a');
else {
printf("%d\n", ac[].Query(str, 'a')-ac[].Query(str, 'a'));
fflush(stdout);
}
}
return ;
}

AC自动机

最新文章

  1. [Q&amp;A] VS 连接 SQLServer 时未找到或无法访问服务器
  2. MySQL语句执行顺序
  3. Javascript数组函数库
  4. appdata文件夹有什么用途?C盘appdata可以删除吗?
  5. Android Fragment之间传值
  6. UDP&mdash;Socket,套接字聊天简单的聊天程序。
  7. 【C#学习笔记】一、基础知识
  8. 设计模式(十一):FACADE外观模式 -- 结构型模式
  9. 寻求c++解答如下三个题目!
  10. LeetCode:same_tree题解
  11. tp的秘密
  12. alpha-咸鱼冲刺day9-紫仪
  13. Win10 Service&#39;MongoDB Server&#39; failed to start. Verify that you have sufficient privileges to start system services【简记】
  14. java框架之MyBatis(1)-入门&amp;动态代理开发
  15. Entity Framework框架 (二)
  16. keil安装
  17. c++のmap的遍历
  18. java 安装环境 疑问(1)
  19. 通过 rufus 创建启动U盘,安装 VMWare Esxi
  20. Django(框架、模板)

热门文章

  1. JavaFX 选择文件 导入Excel文件并解析
  2. Usaco Training [1.3] wormhole
  3. Two types of people with high scores of English exams
  4. MySQL一键生成实体文件的神器-ginbro
  5. 使用python画3D线条
  6. form提交的几种方式
  7. 如何成为PHP程序员?
  8. 浅谈IDEA集成SSM框架(SpringMVC+Spring+MyBatis)
  9. React Native 混合开发与实现
  10. 使用pandoc简单教程