题面

Byteasar 想在墙上涂一段很长的字符,他为了做这件事从字符的前面一段中截取了一段作为模版. 然后将模版重复喷涂到相应的位置后就得到了他想要的字符序列.一个字符可以被喷涂很多次,但是一个位置不能喷涂不同的字符.做一个模版很费工夫,所以他想要模版的长度尽量小,求最小长度是多少.拿样例来说 ababbababbabababbabababbababbaba , 模版为前8个字符ababbaba, 喷涂的过程为: ababbababbabababbabababbababbaba

分析

仔细分析题意之后我们可以发现模板串的三条性质:

1.一个模板串A是要求的文本串B的公共前后缀

2.如果一个模板串B可以覆盖模板串A,那么B是比A更优的一个解

3.如果模板串A可以完全覆盖文本串B,那么A在B中的匹配位置(按照开头算)之间的空格数小于A的长度

由性质1可以猜想,此题大概率是用KMP求解,因为KMP正好可以求出公共前后缀长度。

因此,设next[i]表示前i位的公共前后缀长度,则序列长度只能为next[n],next[next[n]]...

将可能的长度存进数组,对于每个长度的前缀,将其和原串进行匹配,再利用性质3进行判断。

但是这样仍然会超时。

优化:从小到大枚举长度,只要有一个合法就退出。对于长度a,记录最远的匹配位置mx,若存在另

一个长度为b的模板串,且b<mx,则a可以完全覆盖b, 故b一定没有a优。由于a不可行(a在b之前被枚举,若a可行,就不会枚举b了),b一定也不可行,直接跳过

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 500005
using namespace std;
int n,m,sz;
int next[maxn];
int f[maxn];
int len[maxn];
char a[maxn],b[maxn];
int mx;
int check(int m){
    for(int i=1,j=0;i<=n;i++){
        while(j>0&&(j==m||b[i]!=a[j+1]) )j=next[j];
        if(b[i]==a[j+1]) j++;
        f[i]=j;
    }
    bool flag=false;
    int last=1;
    for(int i=1;i<=n;i++){
        if(f[i]==m){
            flag=true;
            if(i-last-1>=m) return 0;
            last=i;
            mx=max(mx,i);
        }
    }
    if(flag) return 1;
    else return 0;
}
int main(){
    scanf("%s",a+1);
    n=strlen(a+1);
    next[1]=0;
    for(int i=1;i<=n;i++) b[i]=a[i];
    for(int i=2,j=0;i<=n;i++){
        while(j>0&&a[i]!=a[j+1]) j=next[j];
        if(a[i]==a[j+1]) j++;
        next[i]=j;
    }
    sz=0;
    for(int i=n;i;i=next[i]){
        len[++sz]=i;
    }
    int ans=n;
    for(int i=sz;i>=0;i--){
        if(len[i]<=mx) continue;
        if(check(len[i])){
            ans=len[i];
            break;
        }
    }
    printf("%d\n",ans);
} 

luogu 3426题解 (KMP)的更多相关文章

  1. [BZOJ 1535] [Luogu 3426]SZA-Template (KMP+fail树+双向链表)

    [BZOJ 1535] [Luogu 3426]SZA-Template (KMP+fail树+双向链表) 题面 Byteasar 想在墙上涂一段很长的字符,他为了做这件事从字符的前面一段中截取了一段 ...

  2. BZOJ 1100 &&luogu 3454(计算几何+KMP)

    题面 给定一个多边形,求对称轴数量. 分析 初看这似乎是一道计算几何的题目,但是如果暴力枚举对称轴,再去判断对称轴两边的边和角是否相等,时间复杂度为\(O(n^2)\),显然会TLE 问题转换 顺时针 ...

  3. POJ3080 Blue Jeans 题解 KMP算法

    题目链接:http://poj.org/problem?id=3080 题目大意:给你N个长度为60的字符串(N<=10),求他们的最长公共子串(长度>=3). 题目分析:KMP字符串匹配 ...

  4. HDU1711 Number Sequence 题解 KMP算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 题目大意:最基础的字符串匹配,只不过这里用整数数组代替了字符串. 给你两个数组 \(a[1..N ...

  5. HDU1686 Oulipo 题解 KMP算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1686 题目大意:给你一个子串t和一个母串s,求s中有多少个子串t. 题目分析:KMP模板题. cal_ ...

  6. HDU3336 Count the string 题解 KMP算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3336 题目大意:找出字符串s中和s的前缀相同的所有子串的个数. 题目分析:KMP模板题.这道题考虑 n ...

  7. Luogu P1993 题解

    p1993 小康的农场 CSP_S 1=之后就没怎么写题解.. 推荐博客食用 预备知识 明显这是一道差分约束的题,以下简称差分 有些人可能不了解差分,请点 [传送门] 至于用差分做的题的特征,无一都是 ...

  8. HDU3746 Teacher YYF 题解 KMP算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3746 题目大意:给你一个串 \(s\) ,要求 \(s\) 的开头或结尾添加最少的字符,使得添加后的串 ...

  9. POJ2185 Milking Grid 题解 KMP算法

    题目链接:http://poj.org/problem?id=2185 题目大意:求一个二维的字符串矩阵的最小覆盖子矩阵,即这个最小覆盖子矩阵在二维空间上不断翻倍后能覆盖原始矩阵. 题目分析:next ...

随机推荐

  1. 基于iview使用jsx扩展成可编辑的表格

    <template> <div> <Table :columns="columns" :data="data"></T ...

  2. springboot中常用注解总结

    1.@RestController(组合注解):标注在类上,等价于@Controller和@Responsebody @Controller:将该类标记为Controller层的类,并且注入到Spri ...

  3. CF1103D Codeforces Round #534 (Div. 1) Professional layer 状压 DP

    题目传送门 https://codeforces.com/contest/1103/problem/D 题解 失去信仰的低水平选手的看题解的心路历程. 一开始看题目以为是选出一些数,每个数可以除掉一个 ...

  4. 【机器人M号】题解

    题目 题目描述 3030年,Macsy正在火星部署一批机器人. 第1秒,他把机器人1号运到了火星,机器人1号可以制造其他的机器人. 第2秒,机器人1号造出了第一个机器人--机器人2号. 第3秒,机器人 ...

  5. [USACO08FEB]连线游戏Game of Lines

    题目背景 Farmer John最近发明了一个游戏,来考验自命不凡的贝茜. 题目描述 Farmer John has challenged Bessie to the following game: ...

  6. springboot-mybatis-demo遇到的坑

    目录 前言 问题&解决 1.初始化Maven工程过慢 2.Spring Boot 集成druid时时区问题和连接超时问题 3.完整工程下载 前言 环境: java version " ...

  7. [ZJU 1003] Crashing Balloon

    ZOJ Problem Set - 1003 Crashing Balloon Time Limit: 2 Seconds      Memory Limit: 65536 KB On every J ...

  8. JS onclick中this用法

    当在dom元素中使用onclick绑定事件的时候,可以使用this来指向该元素对象. 打印输出的内容为: 所以可以通过该this对象来获取子元素 //通过element获取该对象下的一个audio标签 ...

  9. 基于BootStrap的分页代码实现

    public class PageUtil { //targetUrl 访问url totalNum总记录数 currentPage 当前页数 pageSize每页的大小 public static ...

  10. WWDC2014代码和视频下载

    WWDC2014 sample code 地址 http://pan.baidu.com/s/1qWGznnY WWDC2014 videos 地址 https://github.com/liubin ...