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自动机 分块】的更多相关文章

  1. GRE Words Revenge AC自动机 二进制分组

    GRE Words Revenge 题意和思路都和上一篇差不多. 有一个区别就是需要移动字符串.关于这个字符串,可以用3次reverse来转换, 前面部分翻转一下, 后面部分翻转一下, 最后整个串翻转 ...

  2. [HDU 4787] GRE Words Revenge (AC自动机)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4787 题目大意: 给你若干个单词,查询一篇文章里出现的单词数.. 就是被我水过去的...暴力重建AC自 ...

  3. 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 ...

  4. HDU4787 GRE Words Revenge(AC自动机 分块 合并)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4787 Description Now Coach Pang is preparing for ...

  5. 【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|, ...

  6. hdu 4117 GRE Words (ac自动机 线段树 dp)

    参考:http://blog.csdn.net/no__stop/article/details/12287843 此题利用了ac自动机fail树的性质,fail指针建立为树,表示父节点是孩子节点的后 ...

  7. HDU-4787 GRE Words Revenge 解题报告

    这是我之前博客里提到的一道AC自动机的练手题,但是要完成这道题,我之前博客里提到的东西还不够,这里总结一下这道题. 这道题不是一般的裸的AC自动机,它的询问和插入是交叉出现的所以用我之前写的板子不大合 ...

  8. [HDU4787]GRE Words Revenge 解题报告

    这是我之前博客里提到的一道AC自动机的练手题,但是要完成这道题,我之前博客里提到的东西还不够,这里总结一下这道题. 这道题不是一般的裸的AC自动机,它的询问和插入是交叉出现的所以用我之前写的板子不大合 ...

  9. HDU3341 Lost's revenge(AC自动机&&dp)

    一看到ACGT就会想起AC自动机上的dp,这种奇怪的联想可能是源于某道叫DNA什么的题的. 题意,给你很多个长度不大于10的小串,小串最多有50个,然后有一个长度<40的串,然后让你将这个这个长 ...

随机推荐

  1. keycloak集群化的思考

    目录 简介 keycloak中的集群 load balancing负载均衡 暴露客户端IP地址 sticky sessions 和 非sticky sessions shared databases ...

  2. 【Java基础】IO 流

    IO 流 File 类 java.io.File 类是文件和文件目录路径的抽象表示形式,与平台无关. File 能新建.删除.重命名文件和目录,但 File 不能访问文件内容本身. 如果需要访问文件内 ...

  3. SpringBoot嵌入式Servlet容器

    SpringBoot默认是将Tomcat作为嵌入式的servlet容器. 问题: 如何修改嵌入式的servlet容器? 1)在配置文件中设置对应的属性值 server.port=8081 # Tomc ...

  4. Selenium WebDriver 8大定位方式

    Selenium WebDriver 8大定位方式: driver.find_element_by_id() driver.find_element_by_name() driver.find_ele ...

  5. WeihanLi.Npoi 1.14.0 Release Notes

    WeihanLi.Npoi 1.14.0 Release Notes Intro 周末更新了一下项目,开始使用可空引用类型,并且移除了 net45 的支持,仅支持 netstandard2.0 Cha ...

  6. Eclipse中的可视化图形界面设计插件windowbuilder

    对于eclipse平台上的可视化开发工具插件,有windowbuilder.visual editor等,今天就对windowbuilder说明: WindowBuilder功能特性等介绍,参考如下网 ...

  7. SDNU_ACM_ICPC_2021_Winter_Practice_1st [个人赛] 2021.1.19 星期二

    SDNU_ACM_ICPC_2021_Winter_Practice_1st [个人赛] K - Color the ball 题意: 有n个气球,每次都给定两个整数a,b,给a到b内所有的气球涂一个 ...

  8. 细数JS中实用且强大的操作符&运算符

    目录 1,前言 2,代码+应用 2.1,短路运算符 || 2.2,短路运算符 && 2.3,零合并操作符 ?? 2.4,可选链操作符 ?. 2.5,位运算符 & 和 | 2.6 ...

  9. ospf-lite runs over tcp / udp port 8899.

    draft-thomas-reed-ospf-lite-01 - ospf-lite https://tools.ietf.org/html/draft-thomas-reed-ospf-lite-0 ...

  10. 一致性哈希算法C#实现

    一致性hash实现,以下实现没有考虑多线程情况,也就是没有加锁,需要的可以自行加上.因为换行的问题,阅读不太方便,可以拷贝到本地再读. 1 /// <summary> 2 /// 一致性哈 ...