[coci2012]覆盖字符串 AC自动机
给出一个长度为N的小写字母串,现在Mirko有M个若干长度为Li字符串。现在Mirko要用这M个字符串去覆盖给出的那个字符串的。覆盖时,必须保证:
1.Mirko的字符串不能拆开,旋转;
2.Mirko的字符串必须和给出的字符串的某一连续段完全一致才能覆盖,
3.若干次覆盖可以部分重叠
4.Mirko的字符串可以无限使用。
求给出的字符串当中,有多少个字母是无法覆盖的。
小朋友们,作为一名长者,我认为我有必要向你们传授一些人生的经验~;
字符串的一堆函数,慎用慎用;
本人只因没有仔细认真,把strlen(s),strlen(ch)之类的函数写在了循环的里面,造成了无限TLE的惨剧;
图如下:
两个strlen在里面的时候:
#01: Accepted (15ms, 322696KB)
#02: Accepted (15ms, 322696KB)
#03: Accepted (187ms, 322696KB)
#04: Accepted (3234ms, 322696KB)
#05: Accepted (3453ms, 322624KB)
#06: Time Limit Exceeded (?, 322624KB)
#07: Time Limit Exceeded (?, 322624KB)
#08: Time Limit Exceeded (?, 322624KB)
#09: Time Limit Exceeded (?, 322624KB)
#10: Time Limit Exceeded (?, 322624KB)
#11: Time Limit Exceeded (?, 322624KB)
#12: Wrong Answer (5000ms, 322624KB)
#13: Wrong Answer (5000ms, 322624KB)
#14: Time Limit Exceeded (?, 322624KB)
#15: Time Limit Exceeded (?, 322624KB)
#16: Time Limit Exceeded (?, 322624KB)
#17: Wrong Answer (5000ms, 322624KB)
#18: Wrong Answer (5000ms, 322624KB)
#19: Time Limit Exceeded (?, 322624KB)
不知道的会以为我暴力枚举;
一个strlen在循环里的时候:
#01: Accepted (15ms, 345056KB)
#02: Accepted (0ms, 345056KB)
#03: Accepted (0ms, 345056KB)
#04: Accepted (218ms, 345056KB)
#05: Accepted (78ms, 345056KB)
#06: Accepted (93ms, 345056KB)
#07: Accepted (46ms, 345056KB)
#08: Accepted (1656ms, 345056KB)
#09: Time Limit Exceeded (?, 345056KB)
#10: Accepted (93ms, 344984KB)
#11: Accepted (125ms, 344984KB)
#12: Accepted (1562ms, 344984KB)
#13: Time Limit Exceeded (?, 344984KB)
#14: Accepted (171ms, 344984KB)
#15: Accepted (500ms, 344984KB)
#16: Accepted (1640ms, 344984KB)
#17: Wrong Answer (5000ms, 344984KB)
#18: Accepted (250ms, 344984KB)
#19: Accepted (734ms, 344984KB)
还是有三组超了;
没有strlen在里面的时候:
#01: Accepted (0ms, 357712KB)
#02: Accepted (0ms, 357712KB)
#03: Accepted (15ms, 357712KB)
#04: Accepted (78ms, 357712KB)
#05: Accepted (93ms, 357712KB)
#06: Accepted (46ms, 357712KB)
#07: Accepted (46ms, 357712KB)
#08: Accepted (375ms, 357712KB)
#09: Accepted (187ms, 357712KB)
#10: Accepted (93ms, 357712KB)
#11: Accepted (31ms, 357712KB)
#12: Accepted (359ms, 357712KB)
#13: Accepted (328ms, 357712KB)
#14: Accepted (187ms, 357712KB)
#15: Accepted (125ms, 357712KB)
#16: Accepted (359ms, 357712KB)
#17: Accepted (468ms, 357712KB)
#18: Accepted (281ms, 357712KB)
#19: Accepted (140ms, 357712KB)
敲完这道题,我热泪盈眶啊;
同时,我通过这道题敲了好几遍AC自动机模板;
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<ctime>
#include<vector>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
#define LL long long
const int maxn=;
int n,m;
char s[],ch[];
bool vis[][][][][];
int linkk[][],flag[maxn],f[maxn],q[maxn],g[maxn],k[maxn],tail=,head=,len=,next[maxn];
void insert(){
int now=,p=strlen(ch);
for(int i=;i<p;i++){
if(!linkk[now][ch[i]])linkk[now][ch[i]]=++len,g[len]=ch[i];
now=linkk[now][ch[i]];
if(i==p-)flag[now]=p;
}
}
void init(){
//printf("first:%d\n",clock());
scanf("%d%s%d",&n,s,&m);
for(int i=;i<n;i++)s[i]=s[i]-'a'+;
for(int i=;i<n;i++)vis[s[i-]][s[i-]][s[i-]][s[i-]][s[i]]=;
//printf("second:%d\n",clock());
for(int i=;i<=m;i++){
scanf("%s",ch);
bool p=;
int u=strlen(ch);
for(int j=;j<u;j++)ch[j]=ch[j]-'a'+;
for(int j=;j<u;j++)
if(!vis[ch[j-]][ch[j-]][ch[j-]][ch[j-]][ch[j]]){p=;break;}
if(!p)insert();
}
//printf("init:%d\n",clock());
}
void bfs(){
head=,tail=;q[++tail]=;int x=,now=,temp;
while(++head<=tail){
x=q[head];
for(int i=;i<=;i++){
if(linkk[x][i]){
now=linkk[x][i],temp=f[x];
if(x){
while(temp&&!linkk[temp][i])temp=f[temp];
f[now]=linkk[temp][i];
if(flag[f[now]])next[now]=f[now];
else next[now]=next[f[now]];
}
q[++tail]=now;
}
}
}
}
void work(){
bfs();
//printf("bfs:%d\n",clock());
int now=;
for(int i=;i<n;i++){
if(!linkk[now][s[i]]){
int temp=f[now];
while(!linkk[temp][s[i]]&&temp)temp=f[temp];
now=linkk[temp][s[i]];
}
else now=linkk[now][s[i]];
int temp=now;
while(temp){
if(flag[temp])k[i-flag[temp]+]=flag[temp];
temp=next[temp];
}
}
//printf("work:%d\n",clock());
int last=-,sum=;
for(int i=;i<n;i++){
if(k[i])last=max(last,k[i]+i-);
if(i>last)sum++;
}
cout<<sum<<endl;
//cout<<clock()<<endl;
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
init();
work();
}
[coci2012]覆盖字符串 AC自动机的更多相关文章
- JZYZOJ1369 [coci2012]覆盖字符串 AC自动机
http://172.20.6.3/Problem_Show.asp?id=1369 trie树如果不优化就这么往里面放这么多单词肯定超空间+超时,所以需要去掉无用的字符串(不属于原字符串的),但是一 ...
- 模板—字符串—AC自动机(多模式串,单文本串)
模板—字符串—AC自动机(多模式串,单文本串) Code: #include <queue> #include <cstdio> #include <cstring> ...
- 【bzoj1030】: [JSOI2007]文本生成器 字符串-AC自动机-DP
[bzoj1030]: [JSOI2007]文本生成器 首先把匹配任意一个的个数的问题转化为总个数-没有一个匹配的个数 先构造AC自动机,然后枚举每一位的字母以及在自动机上的位置 f[i][j]为第i ...
- 【bzoj3172】: [Tjoi2013]单词 字符串-AC自动机
[bzoj3172]: [Tjoi2013]单词 先用所有单词构造一个AC自动机 题目要求的是每个单词在这个AC自动机里匹配到的次数 每次insert一个单词的时候把路径上的cnt++ 那么点p-&g ...
- 字符串——AC自动机
目录 一.前言 二.思路 三.代码 四.参考资料 一.前言 以前一直没学AC自动机,主要是被名字吓到了,自动AC,这么强的名字肯定很难,学了后才发现,其实不难. AC自动机并不是Acept autom ...
- 【bzoj2434】: [Noi2011]阿狸的打字机 字符串-AC自动机-BIT
[bzoj2434]: [Noi2011]阿狸的打字机 x串在y串上的匹配次数就是y在自动机所有节点上能够通过fail走到x最后一个节点的个数 (就是y串任意一个前缀的后缀能匹配到x的个数)和[bzo ...
- bzoj 3172 单词 ac自动机|后缀数组
题目大意: 给定n个字符串连成了一篇文章,问每个字符串在这篇文章中出现的次数,可重复覆盖 这里ac自动机和后缀数组都可以做 当然后缀数组很容易就解决,但是相对时间消耗高 这里就只讲ac自动机了 将每个 ...
- AC自动机相关Fail树和Trie图相关基础知识
装载自55242字符串AC自动机专栏 fail树 定义 把所有fail指针逆向,这样就得到了一棵树 (因为每个节点的出度都为1,所以逆向后每个节点入度为1,所以得到的是一棵树) 还账- 有了这个东西, ...
- 「kuangbin带你飞」专题十七 AC自动机
layout: post title: 「kuangbin带你飞」专题十七 AC自动机 author: "luowentaoaa" catalog: true tags: - ku ...
随机推荐
- HDU 5937 Equation(DFS+剪枝)
题目链接 Equation 给定1-9这9个数字各自的卡片数,求能构成形如$i + j = k$的等式个数 等式中$i,j,k$必须都为个位数 若两个等式中$i,j,k$不完全相等,则这两个等式为不同 ...
- nfs详解及实现全网备份
1.统一hosts cat /etc/hosts 172.16.1.5 lb01 172.16.1.6 lb02 172.16.1.7 web02 172.16.1.8 web01 172.16.1. ...
- Android(java方法)上实现mp4的分割和拼接 (一)
最近正在处理android上的mp4切割问题.学习了很多mp4的知识,mp4文件按照编码类型,分为mpeg-4,avc这两种:这两种类型的mp4在后面的处理中会有不同的地方. 在Android系 ...
- cocos2d-x step by step(3) Doub le Kill简单的一些小动画
在触控厮混了两年多,不过达到了自己的初衷以及目的. 目前从事cocos2d的更改和调优移植工作. 1 简单的一个图片放大和缩小 auto sprite = Sprite::create("l ...
- 线性回归,logistic回归分类
学习过程 下面是一个典型的机器学习的过程,首先给出一个输入数据,我们的算法会通过一系列的过程得到一个估计的函数,这个函数有能力对没有见过的新数据给出一个新的估计,也被称为构建一个模型.就如同上面的线性 ...
- CMake - boost - 可运行程序 - 静态库
CMake - boost 最后更新日期:2014-04-25by kagula 阅读前提:<CMake入门(二)>.Linux的基本操作 环境: Windows 8.1 64bit英文版 ...
- Objective-C基础笔记(6)Block
Block(代码段)封装了一段代码,能够在不论什么时候运行. Block能够作为函数參数或者函数返回值,而其本身又能够带输入參数或返回值.它和传统的函数指针非常相似,可是有差别:block是inlin ...
- 用Visual C++ 2010 载入动态链接库三部曲(使用第三方库的一般方法)
以下以载入编译好的ACE动态链接库为例说明:这里如果你已经设置了环境变量ACE_ROOT ACE在VS2010下高速配置载入动态链接库三部曲:(这里如果你的ACE文件夹为E:\ACE_wrappers ...
- springMVC学习之验证
验证框中@NotEmpty.@NotBlank.@NotNull乍一看还是容易弄混的.主要使用情况记录一下: @NotEmpty 用在集合类上面 @NotBlank 用在String上面 @NotNu ...
- 最新研发的基于Java的高速开发平台
可自我扩展的智能开发平台 在开发平台设计过程中,联科研发部一開始就希望能研发一套智能开发机制能自己开发自己的平台-即一个能自我修复和自我扩展的开发平台.这个开发平台不但能开发其它应用还能不 ...