【COCI2012】覆盖字符串
【题目描述】
给出一个长度为N的小写字母串,现在Mirko有M个若干长度为Li字符串。现在Mirko要用这M个字符串去覆盖给出的那个字符串的。覆盖时,必须保证:
1.Mirko的字符串不能拆开,旋转;
2.Mirko的字符串必须和给出的字符串的某一连续段完全一致才能覆盖,
3.若干次覆盖可以部分重叠
4.Mirko的字符串可以无限使用。
求给出的字符串当中,有多少个字母是无法覆盖的。
【题解】
很魔性的一道题,一看就知道是AC自动机,这里有个小优化,插入时判断一下:如果模式串是文本的子串就插入。
然后就转化为了线段覆盖问题。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<algorithm>
using namespace std;
#define MAXN 2500010
int n,m,cnt,ans,v[MAXN],q[MAXN],fail[MAXN],k[MAXN],tr[][],vis[][][][][];
char b[MAXN],ch[];
inline int read()
{
int x=,f=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-; ch=getchar();}
while(isdigit(ch)) {x=x*+ch-''; ch=getchar();}
return x*f;
}
void insert(int p)
{
int now=;
for(int i=;i<=p;i++)
{
if(!tr[now][ch[i]]) tr[now][ch[i]]=++cnt;
now=tr[now][ch[i]];
}
v[now]=p;
}
void build()
{
int head=,tail=;
for(int i=;i<;i++) if(tr[][i]) q[++tail]=tr[][i];
while(++head<=tail)
{
int x=q[head];
for(int i=;i<;i++)
{
int y=tr[x][i];
if(!y) continue;
q[++tail]=y;
int temp=fail[x];
while(temp&&!tr[temp][i]) temp=fail[temp];
fail[y]=tr[temp][i];
}
}
}
void work()
{
for(int i=,x=;i<=n;i++)
{
while(x&&!tr[x][b[i]]) x=fail[x]; x=tr[x][b[i]]; int temp=x;
while(temp) {if(v[temp]) k[i-v[temp]+]=v[temp]; temp=fail[temp];}
}
for(int i=,last=;i<=n;i++)
{
if(k[i]) last=max(last,k[i]+i-);
if(last<i) ans++;
}
printf("%d\n",ans);
}
int main()
{
//freopen("cin.in","r",stdin);
//freopen("cout.out","w",stdout);
n=read(); scanf("%s",b+);
for(int i=;i<=n;i++) b[i]=b[i]-'a';
for(int i=;i<=n;i++) vis[b[i]][b[i-]][b[i-]][b[i-]][b[i-]]=;
m=read();
for(int i=;i<=m;i++)
{
scanf("%s",ch+); bool flag=; int len=strlen(ch+);
for(int j=;j<=len;j++) ch[j]=ch[j]-'a';
for(int j=;j<=len;j++) if(!vis[ch[j]][ch[j-]][ch[j-]][ch[j-]][ch[j-]]) {flag=;break;}
if(!flag) insert(len);
}
build();
work();
return ;
}
【COCI2012】覆盖字符串的更多相关文章
- [coci2012]覆盖字符串 AC自动机
给出一个长度为N的小写字母串,现在Mirko有M个若干长度为Li字符串.现在Mirko要用这M个字符串去覆盖给出的那个字符串的.覆盖时,必须保证:1.Mirko的字符串不能拆开,旋转:2.Mirko的 ...
- JZYZOJ1369 [coci2012]覆盖字符串 AC自动机
http://172.20.6.3/Problem_Show.asp?id=1369 trie树如果不优化就这么往里面放这么多单词肯定超空间+超时,所以需要去掉无用的字符串(不属于原字符串的),但是一 ...
- String类常用方法
1.String类的特点,字符串一旦被初始化就不会被改变. 2.String对象定义的两种方式 ①String s = "affdf";这种定义方式是在字符串常量池中创建一个Str ...
- 2、C#面向对象:封装、继承、多态、String、集合、文件(上)
面向对象封装 一.面向对象概念 面向过程:面向的是完成一件事情的过程,强调的是完成这件事情的动作. 面向对象:找个对象帮你完成这件事情. 二.面向对象封装 把方法进行封装,隐藏实现细节,外部直接调用. ...
- StringUtils方法全集
org.apache.commons.lang.StringUtils中方法的操作对象是java.lang.String类型的对象,是JDK提供的String类型操作方法的补充,并且是null安全的( ...
- Redis常用数据类型介绍、使用场景及其操作命令
Redis常用数据类型介绍.使用场景及其操作命令 本文章同时也在cpper.info发布. Redis目前支持5种数据类型,分别是: 1.String(字符串) 2.List(列表) 3.Hash(字 ...
- redis客户端--jedis
一.jedis jedis 是 redis推荐的java客户端.通过Jedis我们可以很方便地使用java代码的方式,对redis进行操作.jedis使用起来比较简单,它的操作方法与redis命令相类 ...
- C中不安全函数
C 中大多数缓冲区溢出问题可以直接追溯到标准 C 库.最有害的罪魁祸首是不进行自变量检查的.有问题的字符串操作(strcpy.strcat.sprintf 和 gets).一般来讲,象“避免使用 st ...
- Redis基础知识之————php-Redis 常用命令专题
Keys del,delete - 删除键 dump - 返回存储在指定键值的序列化版本. exists - 确定键是否存在 expire,setTimeout,pexpire - 设置键的生存时间( ...
随机推荐
- linux下 /boot 分区空间不足及其衍生问题
linux的/boot引导分区有时会提示空间不足的问题,虽不影响系统的正常运行,但是人类天生对于未知的恐惧感总是影响心情的.而且在按安装其他软件的过程在中可能会出现以下问题: gzip: stdout ...
- Ubuntu server 安装samba
安装Samba时,出现了一下问题: linux-image-generic***依赖出现问题,无法安装Samba. 使用apt-get update 更新,吓尿了,全部是忽略,源是系统自带的.改成其他 ...
- BZOJ - 2460 :元素 (贪心&线性基)
相传,在远古时期,位于西方大陆的 Magic Land 上,人们已经掌握了用魔法矿石炼制法杖的技术.那时人们就认识到,一个法杖的法力取决于使用的矿石.一般地,矿石越多则法力越强,但物极必反:有时,人们 ...
- python库之threading
This module constructs higher-level threading interfaces on top of the lower level python库之_threadmo ...
- java中的修辞
1.final修辞 final修辞变量分为两种:基本类型(byte,short,int,long,float,double,char,boolean)也是值类型,则一旦初始化,值不能改变:应用类型(S ...
- ulimit 设置
1. /etc/security/limit.conf * soft nofile 65535 * hard nofile 65535 * soft nproc 65535 * hard nproc ...
- c# HttpWebResponse 调用WebApi
public static class WebApiCaller { public static string HttpPost(string url, string body) { try { // ...
- debian修改主机名
hostnamectl set-hostname aaa 或者 vim /etc/hostname 记得更新 /etc/hosts
- 安装jenkins 的时候 记录默认密码文件为空的情况
1.把文件的权限改成 chmod 777 .jenkins/secrets/initialAdminPassword 然后再使用编辑器打开,密码就出来的 密码文件的地址 /var/root/.hud ...
- java数组复制===clone()
总结:使用方法原理弄清楚 package com.a; public class gjsopb { public static void main(String[] args) { int a[] = ...