HDU4787 GRE Words Revenge【AC自动机 分块】
HDU4787 GRE Words Revenge
题意:
\(N\)次操作,每次记录一个\(01\)串或者查询一个\(01\)串能匹配多少个记录的串,强制在线
题解:
在线的AC自动机,利用分块来降低复杂度,建两个AC自动机,一个大的一个小的,每次往小的里面加字符串,当小的自动机的大小大于一定值之后把小的自动机和大的自动机合并,然后清空小的自动机
每次询问把小的自动机和大的自动机的答案加在一起即可
TIPS:不能把\(fail\)边直接作为子节点来建图,因为之后还要加字符串进去
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 5e6+7;
class ACautomaton{
private:
int fail[MAXN],ch[MAXN][2],tot,last[MAXN],cnt[MAXN];
queue<int> que;
bool updated;
void buildfail(){
for(int i = 0; i < 2; i++){
if(!ch[0][i]) continue;
que.push(ch[0][i]);
fail[ch[0][i]] = last[ch[0][i]] = 0;
}
while(!que.empty()){
int u = que.front();
que.pop();
for(int c = 0; c < 2; c++){
int v = ch[u][c];
if(!v) continue;
int p = fail[u];
while(p and !ch[p][c]) p = fail[p];
fail[v] = ch[p][c];
last[v] = cnt[fail[v]]?fail[v]:last[fail[v]];
que.push(v);
}
}
}
public:
void clear(){
for(int i = 0; i <= tot; i++){
ch[i][0] = ch[i][1] = 0;
cnt[i] = 0;
}
tot = 0; updated = false;
}
void insert(char *s){
updated = true;
int now = 0;
for(int i = 0; s[i]; i++){
int c = s[i] - '0';
if(!ch[now][c]) ch[now][c] = ++tot;
now = ch[now][c];
}
cnt[now] = 1;
}
int mt(int u){
int ret = 0;
while(u){
ret += cnt[u];
u = last[u];
}
return ret;
}
int match(char *s){
if(updated) buildfail();
updated = false;
int ret = 0, now = 0;
for(int i = 0; s[i]; i++){
int c = s[i] - '0';
while(now and !ch[now][c]) now = fail[now];
now = ch[now][c];
ret += mt(now);
}
return ret;
}
int size(){ return tot; }
void merge(ACautomaton &rhs, int u, int v){
updated = true;
for(int c = 0; c < 2; c++){
if(!rhs.ch[v][c]) continue;
if(!ch[u][c]) ch[u][c] = ++tot;
merge(rhs,ch[u][c],rhs.ch[v][c]);
}
cnt[u] |= rhs.cnt[v];
}
}aho[2];
char s[MAXN],t[MAXN];
void solve(int kase){
printf("Case #%d:\n",kase);
aho[0].clear(); aho[1].clear();
int lastres = 0, q;
scanf("%d",&q);
int up = sqrt(MAXN);
while(q--){
scanf("%s",s);
int len = strlen(s+1);
int shift = lastres % len;
t[len] = '\0';
for(int i = 0; i < len; i++) t[i] = s[(i+shift)%len+1];
if(s[0]=='?') printf("%d\n",lastres=aho[0].match(t)+aho[1].match(t));
else{
aho[1].insert(t);
if(aho[1].size()>up){
aho[0].merge(aho[1],0,0);
aho[1].clear();
}
}
}
}
int main(){
int T; scanf("%d",&T);
for(int kase = 1; kase <= T; kase++) solve(kase);
return 0;
}
HDU4787 GRE Words Revenge【AC自动机 分块】的更多相关文章
- GRE Words Revenge AC自动机 二进制分组
GRE Words Revenge 题意和思路都和上一篇差不多. 有一个区别就是需要移动字符串.关于这个字符串,可以用3次reverse来转换, 前面部分翻转一下, 后面部分翻转一下, 最后整个串翻转 ...
- [HDU 4787] GRE Words Revenge (AC自动机)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4787 题目大意: 给你若干个单词,查询一篇文章里出现的单词数.. 就是被我水过去的...暴力重建AC自 ...
- HDU 3341 Lost's revenge AC自动机+dp
Lost's revenge Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- HDU4787 GRE Words Revenge(AC自动机 分块 合并)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for ...
- 【CF587F】Duff is Mad AC自动机+分块
[CF587F]Duff is Mad 题意:给出n个串$s_1,s_2..s_n$,有q组询问,每次给出l,r,k,问你编号在[l,r]中的所有串在$s_k$中出现了多少次. $\sum|s_i|, ...
- hdu 4117 GRE Words (ac自动机 线段树 dp)
参考:http://blog.csdn.net/no__stop/article/details/12287843 此题利用了ac自动机fail树的性质,fail指针建立为树,表示父节点是孩子节点的后 ...
- HDU-4787 GRE Words Revenge 解题报告
这是我之前博客里提到的一道AC自动机的练手题,但是要完成这道题,我之前博客里提到的东西还不够,这里总结一下这道题. 这道题不是一般的裸的AC自动机,它的询问和插入是交叉出现的所以用我之前写的板子不大合 ...
- [HDU4787]GRE Words Revenge 解题报告
这是我之前博客里提到的一道AC自动机的练手题,但是要完成这道题,我之前博客里提到的东西还不够,这里总结一下这道题. 这道题不是一般的裸的AC自动机,它的询问和插入是交叉出现的所以用我之前写的板子不大合 ...
- HDU3341 Lost's revenge(AC自动机&&dp)
一看到ACGT就会想起AC自动机上的dp,这种奇怪的联想可能是源于某道叫DNA什么的题的. 题意,给你很多个长度不大于10的小串,小串最多有50个,然后有一个长度<40的串,然后让你将这个这个长 ...
随机推荐
- rocketmq-cpp-client Visual Studio 2019 编译
rocketmq-cpp-client Visual Studio 2019 编译 rocketmq-cpp-client 是rocketmq c++版本的 所以我们C++ 开发者使用此项目 构建 获 ...
- 【剑指 Offer】03.数组中重复的数字
题目描述 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次.请找出数组中 ...
- 求素数个数的优化-LeetCode204
问题 计数质数 统计所有小于非负整数 n 的质数的数量. 示例: 输入: 10 输出: 4 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 . 第一种解法容易想到但是会 超时 ...
- Docker学习笔记之使用Docker数据卷
Docker数据卷将数据存储到主机而非容器,多个容器需要共享数据时,常常使用数据卷. 1. 为容器设置数据卷(不指定主机目录) 2. 容器与主机之间.容器与容器之间共享数据卷(指定主机目录) 3. 使 ...
- 分别使用 Python 和 Math.Net 调用优化算法
1. Rosenbrock 函数 在数学最优化中,Rosenbrock 函数是一个用来测试最优化算法性能的非凸函数,由Howard Harry Rosenbrock 在 1960 年提出 .也称为 R ...
- kubernets之存活探针
一 存活探针存在的意义 1.1 kubernet通过存活探针(liveness probe)检查容器是否还在运行,可以为pod中的每个容器单独指定存活探针,如果探针执行失败,kubernets会 ...
- MySQL全面瓦解19:游标相关
定义 我们经常会遇到这样的一种情况,需要对我们查询的结果进行遍历操作,并对遍历到的每一条数据进行处理,这时候就会使用到游标. 所以:游标(Cursor)是处理数据的一种存储在MySQL服务器上的数据库 ...
- 同一份数据,Redis为什么要存两次
前言 在 Redis 中,有一种数据类型,当在存储的时候会同时采用两种数据结构来进行分别存储,那么 Redis 为什么要这么做呢?这么做会造成同一份数据占用两倍空间吗? 五种基本类型之集合对象 Red ...
- 转 Fiddler4 手机抓包
Fiddler4 手机抓包 文章转自:https://www.cnblogs.com/zhengna/p/10876954.html 1.要对计算机Fiddler进行配置,允许远程计算机连接. 2. ...
- Jmeter5.1.1 把默认语言调整为中文
进入安装目录:apache-jmeter-5.1.1\bin\ 找到 jmeter.properties文件 搜索" language=en ",前面带有"#" ...