【贪心】【后缀自动机】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem E. Enter the Word
题意:给你一个串,让你从左到右构造这个串,一次操作可以直接在当前串后面添加一个任意字符,或者拷贝当前串的任意一个子串到当前串的后面。问你最少要多少次操作才能构造出这个串。
从前向后贪心,从当前已构造的串的后面开始,尽量往后走,尝试在后缀自动机上转移,直到不能转移为止,便求出了后面的串的在当前串中能找到的最长前缀是多少,然后答案++,然后把这个最长前缀加入后缀自动机接着跑即可。不会证明。
#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的更多相关文章
- 【线段树】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem J. Jedi Training
题意:给你一个序列,支持两种操作:单点修改:询问一个区间中所有相邻位置下标奇偶性均不同的子序列中,和最大的是多少. 线段树每个结点维护四个值: 以奇数下标开始到奇数下标结束的最大子序列和: 以偶数下标 ...
- 【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. 深搜,加两个优化:①倒着从后向前搜:② ...
- 【二分】【三分】【计算几何】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem L. Lines and Polygon
题意:给你一个凸多边形,和多次询问,每次询问给你一条直线,问你这条直线与凸包上的顶点的最近距离是多少. 记当前询问的直线的斜率为K, 先找到与这条直线距离最远的两个点: 就把凸包所有的边当做有向直线进 ...
- 【构造】Ural Championship April 30, 2017 Problem K. King’s island
题意:让你构造一个n个点的简单多边形,使得所有点是整点,并且所有边长是整数,并且没有边平行于坐标轴. 就利用勾股数,如下图这样构造即可,n为偶数时,只需矩形拼成,n为奇数时,封上虚线边即可. #inc ...
- 【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem D. Clones and Treasures
给你一行房间,有的是隐身药水,有的是守卫,有的是金币. 你可以任选起点,向右走,每经过一个药水或金币就拿走,每经过一个守卫必须消耗1个药水,问你最多得几个金币. 药水看成左括号,守卫看成右括号, 就从 ...
- 【哈希表】Ural Championship April 30, 2017 Problem H. Hamburgers
题意:有n群人,每个人有喜欢的汉堡配方:有m家店,给出每家店的每个汉堡的配方,如果存在某个汉堡,其配料表包含某个人喜欢的配方,则这个人喜欢这个汉堡所在的店家.问你对每群人,输出被喜欢的人数最多的店面是 ...
- 【折半枚举】Ural Championship April 30, 2017 Problem G. Glasses with solutions
题意:有n杯盐溶液,给定每杯里面盐的质量以及盐溶液的质量.问你有多少种方案选择一个子集,使得集合里面的盐溶液倒到一个被子里面以后,浓度为A/B. 折半枚举,暴力搜索分界线一侧的答案数,跨越分界线的答案 ...
- 【贪心】【后缀自动机】Gym - 101466E - Text Editor
题意:给你两个串A,B,以及一个整数K,让你找到B的一个尽可能长的前缀,使得其在A串中出现的次数不小于K次. 对A串建立后缀自动机,然后把B串放在上面跑,由于每到一个结点,该结点endpos集合的大小 ...
- BZOJ3998 TJOI2015 弦论 【后缀自动机】【贪心】
Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...
随机推荐
- Machine Learning(CF940F+带修改莫队)
题目链接:http://codeforces.com/problemset/problem/940/F 题目: 题意:求次数的mex,mex的含义为某个集合(如{1,2,4,5})第一个为出现的非负数 ...
- 新疆大学ACM-ICPC程序设计竞赛五月月赛(同步赛) F.猴子排序的期望
题目链接:https://www.nowcoder.com/acm/contest/116/F 题目描述 我们知道有一种神奇的排序方法叫做猴子排序,就是把待排序的数字写在卡片上,然后让猴子把卡片扔在空 ...
- 14、char和varchar的区别?
就长度来说: ♣ char的长度是不可变的; ♣ 而varchar的长度是可变的,也就是说,定义一个char[10]和varchar[10],如果存进去的是‘csdn’,那么char所占的长度依然为1 ...
- Linux简介——(一)
1. 常见操作系统 - 服务端操作系统 : linux.unix.windows server - 单机操作系统 : windows(dos .ucdos.win95.win98.win2000.xp ...
- [干货,阅后进BAT不是梦]面试心得与总结---BAT、网易、蘑菇街
本文转载自:公众号:JANiubility 前言 之前实习的时候就想着写一篇面经,后来忙就给忘了,现在找完工作了,也是该静下心总结一下走过的路程了,我全盘托出,奉上这篇诚意之作,希望能给未来找工作的人 ...
- perl6中函数参数(2)
use v6; #如果参数是可选的, 可以在后面加个?后定义 sub Choo($x, $y?){ say $x+$y; } Choo(); Choo(,); #具名参数, 也就是字典形式的调用 su ...
- 实战手工注入某站,mssql注入
昨天就搞下来的,但是是工具搞得,为了比赛还是抛弃一阵子的工具吧.内容相对简单,可掠过. 报错得到sql语句: DataSet ds2 = BusinessLibrary.classHelper.Get ...
- 【Android framework】am命令启动Activity流程
源码基于Android 4.4. am start -W -n com.dfp.test/.TEstActivity -W:等目标Activity启动后才返回 -n:用于设置Intent的Comp ...
- python基础=== itertools介绍(转载)
原文链接:http://python.jobbole.com/85321/ Python提供了一个非常棒的模块用于创建自定义的迭代器,这个模块就是 itertools.itertools 提供的工具相 ...
- Oracle例外定义
例外名 ORA-XXXXX SQLCODE ACCESS_INTO_NULL ORA-06530 -6530 CASE_NOT_FOUND ORA-06592 -6592 COLLECTION_IS_ ...