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. 弹幕视频播放app案例分析

    产品 哔哩哔哩动画 相对于其他视频播放软件来说,哔哩哔哩动画没有广告影响观看体验,而且内容更偏重于二次元,因此我更倾向于使用它. 第一部分 调研, 评测 #第一次上手体验 用起来还是比较方便,可以快速 ...

  2. CocoaPods 基础知识--------安装 及 使用第三方库

    极客学院:http://www.jikexueyuan.com/course/2665_2.html?ss=1

  3. GPUImage滤镜效果翻译

    #import"GPUImageBrightnessFilter.h"//亮度 #import"GPUImageExposureFilter.h"//曝光 #i ...

  4. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  5. 技术文档分享_linux中生成考核用的GPT分区表结构修复

    注:历史版本,后期改用python实现了 实验一: 目的:用于生成大量模拟破坏GPT分区结构案例,并生成唯一方式修复后的评判方法.故障:在一个完整的GPT分区磁盘上,丢失了GPT主分区表,或备份分区表 ...

  6. tomcat下的web.xml和项目中的web.xml

    Tomcat 服务器中存在一个web.xml文件 在项目文件夹中同样存在一个web.xml文件 那这两个文件有什么区别呢? tomcat中的web.xml是通用的,如果不设置,那么就会默认是同tomc ...

  7. 《网络》:设置三个密码:通过console口连接设备,进入特权模式,登录Telnet

    软件:Cisco Packet Tracer Instructor 软件下载链接在上一篇文章中. 内容:通过设置三个密码,熟悉采用Telnet方式配置交换机的方法. 细节说明:计算机的IP地址和交换机 ...

  8. 作业五:RE 模块模拟计算器

    # !/usr/bin/env python3 # _*_coding:utf-8_*_ ''' 实现模拟计算器的功能: 公式: - * ( (- +(-/) * (-*/ + /*/* + * / ...

  9. 说说cglib动态代理

    前言 jdk中的动态代理通过反射类Proxy和InvocationHandler回调接口实现,要求委托类必须实现一个接口,只能对该类接口中定义的方法实现代理,这在实际编程中有一定的局限性. cglib ...

  10. Spring Security 入门(3-10)Spring Security 的四种使用方式

    原文链接: http://www.360doc.com/content/14/0724/17/18637323_396779659.shtml 下面是作者的一个问题处理