题意:给你一个串,让你从左到右构造这个串,一次操作可以直接在当前串后面添加一个任意字符,或者拷贝当前串的任意一个子串到当前串的后面。问你最少要多少次操作才能构造出这个串。

从前向后贪心,从当前已构造的串的后面开始,尽量往后走,尝试在后缀自动机上转移,直到不能转移为止,便求出了后面的串的在当前串中能找到的最长前缀是多少,然后答案++,然后把这个最长前缀加入后缀自动机接着跑即可。不会证明。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXL 200000
#define MAXC 26
int v[2*MAXL+10],__next[2*MAXL+10],first[2*MAXL+10],e;
void AddEdge(int U,int V){
v[++e]=V;
__next[e]=first[U];
first[U]=e;
}
char s[MAXL+10];
int len;
struct SAM{
int endcnt[2*MAXL+10];
int n,maxlen[2*MAXL+10],minlen[2*MAXL+10],trans[2*MAXL+10][MAXC],slink[2*MAXL+10];
void clear(){
for(int i=0;i<=n;++i){
endcnt[i]=maxlen[i]=minlen[i]=slink[i]=first[i]=0;
memset(trans[i],0,sizeof(trans[i]));
}
n=e=0;
}
int new_state(int _maxlen,int _minlen,int _trans[],int _slink){
maxlen[n]=_maxlen;
minlen[n]=_minlen;
for(int i=0;i<MAXC;++i){
if(_trans==NULL){
trans[n][i]=-1;
}
else{
trans[n][i]=_trans[i];
}
}
slink[n]=_slink;
return n++;
}
int add_char(char ch,int u){
if(u==-1){
return new_state(0,0,NULL,-1);
}
int c=ch-'a';
int z=new_state(maxlen[u]+1,-1,NULL,-1);
endcnt[z]=1;
int v=u;
while(v!=-1 && trans[v][c]==-1){
trans[v][c]=z;
v=slink[v];
}
if(v==-1){
minlen[z]=1;
slink[z]=0;
return z;
}
int x=trans[v][c];
if(maxlen[v]+1==maxlen[x]){
minlen[z]=maxlen[x]+1;
slink[z]=x;
return z;
}
int y=new_state(maxlen[v]+1,-1,trans[x],slink[x]);
slink[y]=slink[x];
minlen[x]=maxlen[y]+1;
slink[x]=y;
minlen[z]=maxlen[y]+1;
slink[z]=y;
int w=v;
while(w!=-1 && trans[w][c]==x){
trans[w][c]=y;
w=slink[w];
}
minlen[y]=maxlen[slink[y]]+1;
return z;
}
}sam;
int ans;
int main(){
// freopen("e.in","r",stdin);
scanf("%s",s);
len=strlen(s);
int U=sam.add_char(0,-1);
int i=0;
while(i<len){
if(sam.trans[0][s[i]-'a']==-1){
U=sam.add_char(s[i],U);
++i;
}
else{
int j=i,V=0;
while(V!=-1 && j<len){
V=sam.trans[V][s[j]-'a'];
++j;
}
if(j==len && V!=-1){
++ans;
break;
}
for(int k=i;k<j-1;++k){
U=sam.add_char(s[k],U);
}
i=j-1;
}
++ans;
}
printf("%d\n",ans);
return 0;
}

【贪心】【后缀自动机】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem E. Enter the Word的更多相关文章

  1. 【线段树】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem J. Jedi Training

    题意:给你一个序列,支持两种操作:单点修改:询问一个区间中所有相邻位置下标奇偶性均不同的子序列中,和最大的是多少. 线段树每个结点维护四个值: 以奇数下标开始到奇数下标结束的最大子序列和: 以偶数下标 ...

  2. 【DFS】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem D. Divisibility Game

    题意:给你一个序列,长度不超过52,每个元素不超过13.让你重新对这个序列排序,sum(i)表示i的前缀和,使得排序过后,对每个i,都有sum(i)%i==0. 深搜,加两个优化:①倒着从后向前搜:② ...

  3. 【二分】【三分】【计算几何】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem L. Lines and Polygon

    题意:给你一个凸多边形,和多次询问,每次询问给你一条直线,问你这条直线与凸包上的顶点的最近距离是多少. 记当前询问的直线的斜率为K, 先找到与这条直线距离最远的两个点: 就把凸包所有的边当做有向直线进 ...

  4. 【构造】Ural Championship April 30, 2017 Problem K. King’s island

    题意:让你构造一个n个点的简单多边形,使得所有点是整点,并且所有边长是整数,并且没有边平行于坐标轴. 就利用勾股数,如下图这样构造即可,n为偶数时,只需矩形拼成,n为奇数时,封上虚线边即可. #inc ...

  5. 【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem D. Clones and Treasures

    给你一行房间,有的是隐身药水,有的是守卫,有的是金币. 你可以任选起点,向右走,每经过一个药水或金币就拿走,每经过一个守卫必须消耗1个药水,问你最多得几个金币. 药水看成左括号,守卫看成右括号, 就从 ...

  6. 【哈希表】Ural Championship April 30, 2017 Problem H. Hamburgers

    题意:有n群人,每个人有喜欢的汉堡配方:有m家店,给出每家店的每个汉堡的配方,如果存在某个汉堡,其配料表包含某个人喜欢的配方,则这个人喜欢这个汉堡所在的店家.问你对每群人,输出被喜欢的人数最多的店面是 ...

  7. 【折半枚举】Ural Championship April 30, 2017 Problem G. Glasses with solutions

    题意:有n杯盐溶液,给定每杯里面盐的质量以及盐溶液的质量.问你有多少种方案选择一个子集,使得集合里面的盐溶液倒到一个被子里面以后,浓度为A/B. 折半枚举,暴力搜索分界线一侧的答案数,跨越分界线的答案 ...

  8. 【贪心】【后缀自动机】Gym - 101466E - Text Editor

    题意:给你两个串A,B,以及一个整数K,让你找到B的一个尽可能长的前缀,使得其在A串中出现的次数不小于K次. 对A串建立后缀自动机,然后把B串放在上面跑,由于每到一个结点,该结点endpos集合的大小 ...

  9. BZOJ3998 TJOI2015 弦论 【后缀自动机】【贪心】

    Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...

随机推荐

  1. DotNETCore 学习笔记 MVC视图

    Razor Syntax Reference Implicit Razor expressions <p>@DateTime.Now</p> <p>@DateTim ...

  2. POJ 2991 Crane (线段树)

    题目链接 Description ACM has bought a new crane (crane -- jeřáb) . The crane consists of n segments of v ...

  3. patch需要数据格式前端算法,patch算法基础,两个对象对比取差异属性

    在我们的前端开发过程中,表单是最常见不过的了,一般我们创建表单的时候习惯使用post方法来提交数据,编辑表单时候喜欢put,但是当表单的数据非常多的时候,编辑起来很麻烦,首先需要获取初始化数据,然后把 ...

  4. 14、char和varchar的区别?

    就长度来说: ♣ char的长度是不可变的; ♣ 而varchar的长度是可变的,也就是说,定义一个char[10]和varchar[10],如果存进去的是‘csdn’,那么char所占的长度依然为1 ...

  5. canvas_基于canvan绘制的双半圆环进度条

    效果图 实现原理: 1.使用canvas绘制两个半圆弧,底图灰色半圆弧和颜色进度圆弧. 2.利用setInterval计时器,逐步改变颜色进度条,达到进度条的效果. 效果代码: <!DOCTYP ...

  6. Kendo Grid:将Edit button 移到grid view 得顶部

    因为kendo grid 得toolbar 里不包括Edit button,所以我们要先用template 创建一个自定义得edit button,然后再对这个button实现edit 功能. < ...

  7. CentOS7修改默认运行级别

    新装了一个虚拟机,图形界面启动太慢,想调整一下按照以前的经验改运行级别,输入: vi /etc/inittab 然后发现跟之前不一样了,在inittab设置不再生效: # inittab is no ...

  8. xtrabackup 安装、备份和恢复

    xtrabackup 版本对应: 2.4 专针对 5.7 开发的,兼容 5.6, 5.5 2.3 针对 5.6 开发的,兼容5.5 2.2 针对5.5 开发的 安装包下载: wget https:// ...

  9. pycaffe做识别时通道转换问题

    转自---------------------  作者:Peanut_范  来源:CSDN  原文:https://blog.csdn.net/u013841196/article/details/7 ...

  10. vue知识点(1)

    处理用户输入 v-on指令添加一个事件监听器 div id="app-5"> <p>{{ message }}</p> <button v-on ...