题目链接:http://codeforces.com/gym/100431/

考虑到对于一个串β,能cover它的最短的α必然是它的border的某个前缀,或者是这个β本身。

所谓border,就是next[len(β)],直观含义是除了串本身以外,使得前缀等于后缀的最长的一段前缀。

发现如果border的两倍就能覆盖整个串,那么问题的规模就减半了,只要求出能cover这个border的最短的串即可。这个关系是具有传递性的,只要border够长,就一直可以推下去。而这种关系可以通过一个last数组实现路径压缩。

如果border的两倍不能覆盖整个串,那就要看border的哪一个前缀可以了,那么哪些前缀可以呢?只有哪些border的border才有可能可以。这是为什么呢?因为只有哪些border的border,才是β串的公共前后缀。那么我们通过一个far数组,维护每一个前缀最远能够覆盖到的位置,动态维护这个数组,通过last数组路径压缩加速即可。

要注意的是far数组的更新要一路更新到底,否则无法把信息维护全。

#include<bits/stdc++.h>
using namespace std; void kmp_pre(char x[],int m,int nxt[])
{
int i,j;
j=nxt[]=-;
i=;
while(i<m)
{
while(-!=j && x[i]!=x[j])j=nxt[j];
nxt[++i]=++j;
}
} const int maxn=;
char s[maxn];
int nxt[maxn];
int last[maxn];
int far[maxn]; int main()
{
freopen("cover.in","r",stdin);
freopen("cover.out","w",stdout);
scanf("%s",s);
int l=strlen(s);
kmp_pre(s,l,nxt);
for (int i=;i<=l;i++) if (nxt[i]*>=i) last[i]=last[nxt[i]]; else last[i]=i;
for (int i=;i<=l;i++)
{
int j=last[i];
far[j]=i;
int now=i;
while (j)
{
if (far[j]>=i-j)
{
now=j;
far[now]=i;
}
j=last[nxt[j]];
}
printf("%d ",now);
}
return ;
}

[codeforces/gym/100431/E]KMP关于border的理解的更多相关文章

  1. Codeforces Gym 100431B Binary Search 搜索+组合数学+高精度

    原题链接:http://codeforces.com/gym/100431/attachments/download/2421/20092010-winter-petrozavodsk-camp-an ...

  2. Codeforces Gym 100431D Bubble Sort 水题乱搞

    原题链接:http://codeforces.com/gym/100431/attachments/download/2421/20092010-winter-petrozavodsk-camp-an ...

  3. Codeforces Gym 100431A Achromatic Number 欧拉回路

    原题链接:http://codeforces.com/gym/100431/attachments/download/2421/20092010-winter-petrozavodsk-camp-an ...

  4. Codeforces Gym 101252D&&floyd判圈算法学习笔记

    一句话题意:x0=1,xi+1=(Axi+xi%B)%C,如果x序列中存在最早的两个相同的元素,输出第二次出现的位置,若在2e7内无解则输出-1. 题解:都不到100天就AFO了才来学这floyd判圈 ...

  5. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

  6. Codeforces Gym 101623A - 动态规划

    题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求划分成最少的段数,然后将这些段排序使得新序列单调不减. 考虑将相邻的相等的数缩成一个数. 假设没有分成了$n$段,考虑最少能够减少多少划分 ...

  7. 【Codeforces Gym 100725K】Key Insertion

    Codeforces Gym 100725K 题意:给定一个初始全0的序列,然后给\(n\)个查询,每一次调用\(Insert(L_i,i)\),其中\(Insert(L,K)\)表示在第L位插入K, ...

  8. Codeforces gym 101343 J.Husam and the Broken Present 2【状压dp】

     2017 JUST Programming Contest 2.0 题目链接:Codeforces gym 101343 J.Husam and the Broken Present 2 J. Hu ...

  9. codeforces gym 100553I

    codeforces gym 100553I solution 令a[i]表示位置i的船的编号 研究可以发现,应是从中间开始,往两边跳.... 于是就是一个点往两边的最长下降子序列之和减一 魔改树状数 ...

随机推荐

  1. pyecharts数据分析及展示

    仅仅从网上爬下数据当然是不够用的,主要还得对数据进行分析与展示,大部分人都看重薪资,但是薪资数据有的是*k/月,有的是*万/月,还有*万/年等等,就要对数据进行清理 将所有单位统一化,全部换算成统一单 ...

  2. ubuntu下安装LAMP环境遇到的一些小问题

    0x00 今天在服务器上重新弄了一下lamp环境 安装的过程中遇到了不少小问题 记录一下解决的方案吧 服务器安装的是ubuntu 16.04.1 0x01 首先在用 apt-get install 安 ...

  3. 一步一步学Linq to sql(四):查询句法

    select 描述:查询顾客的公司名.地址信息 查询句法: var 构建匿名类型1 = from c in ctx.Customers select new { 公司名 = c.CompanyName ...

  4. Python的import导入与时间

    一.模块与包 模块,在Python可理解为对应于一个文件.在创建了一个脚本文件后,定义了某些函数和变量.你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量.一般用module_name. ...

  5. 【java并发编程实战】第七章:取消与关闭

    停止线程的几种方式 一般的逻辑停止 public class ThreadInterruptTest { public static volatile boolean cancel = true; p ...

  6. Laxcus大数据管理系统2.0(4)- 第一章 基础概述 1.3 节点

    1.3 节点 按照我们给Laxcus集群的设计定义,Laxcus集群被分为内部和外部两个网络环境.内部网络由集群的所有权人负责实施和管理,为保证集群能够有效可靠运行,需要遵守一系列的集群部署和管理规定 ...

  7. NLP系列-中文分词(基于统计)

    上文已经介绍了基于词典的中文分词,现在让我们来看一下基于统计的中文分词. 统计分词: 统计分词的主要思想是把每个词看做是由字组成的,如果相连的字在不同文本中出现的次数越多,就证明这段相连的字很有可能就 ...

  8. shell功能

    日志切割: function rotate() { logs_path=$ echo Rotating Log: $ cp ${logs_path} ${logs_path}.$(date -d &q ...

  9. 安装CentOS 5.x与多重引导小技巧

    不建议使用Virtualbox安装Linux来学习!本处是学习在计算机上安装Linux. 但现在条件有限,就先使用Virtualbox练习!

  10. input设置为readonly后js设置intput的值后台仍然可以接收到

    今天发现一个奇怪现象,一个input属性readonly的值被设置为readonly,然后有前台js给input设置了新值. 虽然前台看不到效果,但是提交到后台后,仍然可以接收到新值,感觉很奇怪. 我 ...