Description

  Now Coach Pang is preparing for the Graduate Record Examinations as George did in 2011. At each day, Coach Pang can:

   "+w": learn a word w

   "?p": read a paragraph p, and count the number of learnt words. Formally speaking, count the number of substrings of p which is a learnt words.

  Given the records of N days, help Coach Pang to find the count. For convenience, the characters occured in the words and paragraphs are only '0' and '1'.

 

 

Solution

这题网上大部分题解都是错的,只能说数据太水

首先这题用到AC自动机,如果暴力做每一组询问需要getfail一次,但是这样做也能AC.

考虑合并,我们建立两个AC自动机,保证其中一个大小\(<\sqrt{n}\) 每一次对小的进行getfail,复杂度只有\(O(\sqrt{n})\),如果小的 \(size\) 达到了 \(\sqrt{n}\),考虑暴力合并,复杂度 \(O(\sqrt{n})\)

注意一个细节,一个单词只能学习一次,所以每加一次需要判断之前是否存在,网上大部分都没有做这个

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=100005,M=600005;
int m,kase=0,ans=0,B=100,root=0;char s[M*10];
queue<int>q;
struct Ac{
int size,ch[M][2],fail[M],val[M];
int newnode(){
size++;
ch[size][0]=ch[size][1]=0;
fail[size]=0;val[size]=0;
return size;
}
void clear(){
size=-1;newnode();
}
void ins(char *S){
int x,len=strlen(s),p=root;
for(int i=1;i<len;i++){
x=S[i]-'0';
if(ch[p][x])p=ch[p][x];
else ch[p][x]=newnode(),p=ch[p][x];
}
val[p]|=1;
}
void getfail(){
while(!q.empty())q.pop();
q.push(root);int x,u,v;
while(!q.empty()){
x=q.front();q.pop();
for(int i=0;i<=1;i++){
if(!ch[x][i])continue;
u=fail[x];
while(u && !ch[u][i])u=fail[u];
if(ch[u][i] && ch[u][i]!=ch[x][i])
fail[ch[x][i]]=ch[u][i];
v=ch[x][i];q.push(v);
}
}
}
int query(char *S){
int x,len=strlen(S),p=root,ret=0,u;
for(int i=1;i<len;i++){
x=S[i]-'0';
while(p && !ch[p][x])p=fail[p];
p=ch[p][x];u=p;
while(u)ret+=val[u],u=fail[u];
}
return ret;
}
bool check(char *S){
int len=strlen(S),x,p=root;
for(int i=1;i<len;i++){
x=S[i]-'0';
if(!ch[p][x])return false;
p=ch[p][x];
}
return val[p];
}
}A,C;
void dfs(int art,int crt){
int x;
for(int i=0;i<=1;i++)
if(C.ch[crt][i]){
if(!A.ch[art][i])A.ch[art][i]=A.newnode();
x=A.ch[art][i];A.val[x]|=C.val[C.ch[crt][i]];
dfs(x,C.ch[crt][i]);
}
}
char b[N];
void Moveit(){
int k=ans,len=strlen(s),p=1;
k%=(len-1);
for(int i=1;i<=k;i++)b[i]=s[i];
for(int i=1;k<len-1;i++)s[i]=s[++k];
for(int i=len-(ans%(len-1));i<len;i++)s[i]=b[p++];
}
void work()
{
printf("Case #%d:\n",++kase);
scanf("%d",&m);
A.clear();C.clear();ans=0;
while(m--){
scanf("%s",s);
Moveit();
if(s[0]=='+'){
if(A.check(s) || C.check(s))continue;
C.ins(s);
if(C.size>B){dfs(0,0);A.getfail();C.clear();}
else C.getfail();
}
else ans=A.query(s)+C.query(s),printf("%d\n",ans);
}
} int main()
{
int T;cin>>T;
while(T--)work();
return 0;
}

HDU 4787 GRE Words Revenge的更多相关文章

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

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

  2. ●HDU 4787 GRE Words Revenge

    题链: http://acm.hdu.edu.cn/showproblem.php?pid=4787 题解: AC自动机(强制在线构造) 题目大意: 有两种操作, 一种为:+S,表示增加模式串S, 另 ...

  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. GRE Words Revenge AC自动机 二进制分组

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

  5. HDU4787 GRE Words Revenge【AC自动机 分块】

    HDU4787 GRE Words Revenge 题意: \(N\)次操作,每次记录一个\(01\)串或者查询一个\(01\)串能匹配多少个记录的串,强制在线 题解: 在线的AC自动机,利用分块来降 ...

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

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

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

  8. HDU 5922 Minimum’s Revenge 【模拟】 (2016CCPC东北地区大学生程序设计竞赛)

    Minimum's Revenge Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

  9. HDU P3341 Lost's revenge 题解+数据生成器

    Lost and AekdyCoin are friends. They always play "number game"(A boring game based on numb ...

随机推荐

  1. 201621123040《Java程序设计》第4周学习总结

    1.本周学习总结 1.1写出你认为本周学习中比较重要的知识点关键词 关键词:继承 多态性 基本语法 重新定义Override 1.2尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多 ...

  2. 从PRISM开始学WPF(六)MVVM(二)Command?

    从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? ...

  3. git(一)快速入门

    1.设置用户名 git config --global user.name '你的用户名' ​ 2.设置用户名邮箱 git config --global user.email '你的邮箱' ​ 3. ...

  4. 09-TypeScript中的继承

    在后端开发语言中,继承是非常重要的概念,继承可以让子类具有父类的成员和方法,通过实例化子类,就可以访问父类的成员和方法. 在JavaScript中,需要通过原型模式来模拟继承的实现.而在TypeScr ...

  5. C#中委托。

    委托(delegate):是一个类型.其实winform中控件的事件也是特殊的委托类型. 如: 自定义委托:自定义委托在winform中的用法. 当要在子线程中更新UI时,必须通过委托来实现. pri ...

  6. MongoDb进阶实践之五 MongoDB修改命令详述

    一.引言         上一篇文章我们已经详细介绍了MongoDB数据库的有关查询的内容,但是这只是所有查询命令的冰山一角.所有查询命令都写完也没有必要,我只是写了一些常用的命令,对MongoDB的 ...

  7. 深度学习之 GAN 进行 mnist 图片的生成

    深度学习之 GAN 进行 mnist 图片的生成 mport numpy as np import os import codecs import torch from PIL import Imag ...

  8. MySQL8.0 原子DDL

    Edit MySQL8.0 原子DDL 简介 MySQL8.0 开始支持原子 DDL(atomic DDL),数据字典的更新,存储引擎操作,写二进制日志结合成了一个事务.在没有原子DDL之前,DROP ...

  9. Mysql 5.1的坑

    1.数据库表是区分大小写的 之前程序在5.7数据库没问题,测试环境上数据库是5.1的,就提示表找不到. 2.同样的sql,在5.1上会提示事务获取锁失败,超时返回.而5.7上正常.原因暂未找到.

  10. 复习HTML+CSS(2)

    n  项目符号嵌套编号思路 标签的内容(文本.项目符号.表格.图片等)必须放在最底层标记中. n  图片标记(行内元素,单边标记) l  语法:<img 属性 = "值"&g ...