题面

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. 关于CSS你应该知道的基础知识 - 盒模型篇

    浏览器渲染引擎通过盒模型的方式来布局html元素.我们可以将每一个html元素都看做是一个盒子,每一个盒子都有长和款,多个这样的盒子组成了我们的网页. Margin,Border,Padding 每一 ...

  2. 7.docker私有registry

    一.Docker Registry分类 Registry用于保存docker镜像,包括镜像的层次结构和元数据.都是基于https或者http工作的. 用户可自建Registry,也可使用官方的Dock ...

  3. 6411. 【NOIP2019模拟11.06】上网

    题目描述 Description Input Output 若无解,则输出"Impossible". 否则第一行输出"Possible",第二行输出 n 个正整 ...

  4. idea 打包model 为jar包

    1,在项目上鼠标右键 --> Open Module Settings 2, Artifacts --> + --> JAR --> From modules with dep ...

  5. vue.js条件渲染 v-if else-if v-for

    v-if: 在字符串模板中,如 Handlebars ,我们得像这样写一个条件块: {{#if ok}} <!-- Handlebars 模板 --> <h1>Yes</ ...

  6. android中使用Application

    在android开发过程中,我们可能存储一些全局的变量,最好在正在app的任何一个activity或者service中都可以访问到,这时我们可以使用application. 我们的一个应用就叫appl ...

  7. 170903-关于MyBatis

    MyBatis总体介绍:  MyBatis实际上是Ibatis3.0版本以后的持久化层框架[也就是和数据库打交道的框架]! 和数据库打交道的技术有: 原生的JDBC技术--->Spring的Jd ...

  8. 冲刺周四The Fourth Day

    一.Fourth Day照片 二.项目分工 三.今日份燃尽图 四.项目进展 码云团队协同环境构建完毕 利用Leangoo制作任务分工及生成燃尽图 完成AES加解密部分代码 用代码实现对文件的新建.移动 ...

  9. 用Python给头像加上圣诞帽或圣诞老人小图标

    随着圣诞的到来,想给给自己的头像加上一顶圣诞帽.如果不是头像,就加一个圣诞老人陪伴.   用Python给头像加上圣诞帽,看了下大概也都是来自2017年大神的文章:https://zhuanlan.z ...

  10. python中导入sklearn中模块提示ImportError: DLL load failed: 找不到指定的程序。

    python版本:3.7 平台:windows 10 集成环境:Anaconda3.7 64位 在jupyter notebook中导入sklearn的相关模块提示ImportError: DLL l ...