重复旋律5

时间限制:10000ms
单点时限:2000ms
内存限制:512MB

描述

小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为一段数构成的数列。

现在小Hi想知道一部作品中出现了多少不同的旋律?

输入

共一行,包含一个由小写字母构成的字符串。字符串长度不超过 1000000。

输出

一行一个整数,表示答案。

样例输入
aab
样例输出
5

2017-11-22:从代码看,是比ac自动机优美,但是ac自动机是基础在kmp和字典树上面,学习起来很快,然而后缀自动机就灰常难以YY啦。

目前感觉似懂非懂,等把后面几个题AC了再回来整理吧。

 

2017-11-25:三天,做了几个题之后,基本上是弄懂了。感觉后缀自动机很强大,打算再花一周来练习。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=;
int tot=,n,slink[*N],trans[*N][],minlen[*N],maxlen[*N];
char str[N];
ll ans=;
int newstate(int _maxlen,int _minlen,int* _trans,int _slink) {
maxlen[++tot]=_maxlen;
minlen[tot]=_minlen;
slink[tot]=_slink;
if(_trans)
for(int i=; i<; i++)
trans[tot][i]=_trans[i];
else for(int i=;i<;i++)
trans[tot][i]=-;
return tot;
}
int add_char(char ch,int u) {
int c=ch-'a',v=u;
int z=newstate(maxlen[u]+,-,NULL,);
while(v!=-&&trans[v][c]==-) {
trans[v][c]=z;
v=slink[v];
}
if(v==-) {
minlen[z]=;
slink[z]=;
return z;
}
int x=trans[v][c];
if(maxlen[v]+==maxlen[x]) {
slink[z]=x;
minlen[z]=maxlen[x]+;
return z;
}
int y=newstate(maxlen[v]+,-,trans[x],slink[x]);
slink[z]=slink[x]=y;
minlen[x]=minlen[z]=maxlen[y]+;
while(v!=-&&trans[v][c]==x) {
trans[v][c]=y;
v=slink[v];
}
minlen[y]=maxlen[slink[y]]+;
return z;
}
int main() {
scanf("%s",str);
int len=strlen(str),pre=;
memset(trans[],-,sizeof(trans[]));
slink[]=-;
for(int i=; i<len; i++) {
pre=add_char(str[i],pre);
}
for(int i=; i<=tot; i++) {
ans+=maxlen[i]-minlen[i]+;
}
printf("%lld\n",ans);
return ;
}

做了HDU4641再回来改动一下,minlen[i]=maxlen[slink[i]],所以没必要保存minlen了。代码稍微简短了一点:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
const int maxn=;
int tot,slink[*maxn],trans[*maxn][],maxlen[*maxn];
char str[*maxn];
int N,M,K,num[*maxn],last;
long long ans;
void init()
{
ans=tot=;
last=;
memset(trans[],-,sizeof(trans[]));
slink[]=-; maxlen[]=;
}
void add_char(char chr)
{
int c=chr-'a';
int p=last,np=++tot;
maxlen[np]=maxlen[p]+;
memset(trans[np],-,sizeof(trans[np]));
num[np]=;
while(p!=-&&trans[p][c]==-) trans[p][c]=np,p=slink[p];
if(p==-) slink[np]=;
else
{
int q=trans[p][c];
if(maxlen[q]!=maxlen[p]+)
{
int nq=++tot;
memcpy(trans[nq],trans[q],sizeof(trans[q])); num[nq]=num[q];
maxlen[nq]=maxlen[p]+;
slink[nq]=slink[q];
slink[np]=slink[q]=nq;
while(p!=-&&trans[p][c]==q) trans[p][c]=nq,p=slink[p];
}
else slink[np]=q;
}
last=np;
}
int main() {
init();
scanf("%s",str);
N=strlen(str);
for(int i=; i<N; i++) add_char(str[i]);
for(int i=;i<=tot;i++) ans+=maxlen[i]-maxlen[slink[i]];
printf("%lld\n",ans);
return ;
}

HihoCoder1445 重复旋律5(后缀自动机)的更多相关文章

  1. HihoCoder1449 重复旋律6(后缀自动机)

    描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数列. 现在小Hi想知道一部作品中所有长度为K的旋律中出现次数最多的旋律的出现次数.但是K不是固定的,小Hi想知道对 ...

  2. hihoCoder.1465.后缀自动机五 重复旋律8(后缀自动机)

    题目链接 \(Description\) 给定母串S,求模式串的循环同构串在S中的出现次数. \(Solution\) 将模式串s复制一遍,在母串的SAM上匹配,记录以每个位置作为后缀所能匹配的最大长 ...

  3. hihoCoder 1403 后缀数组一·重复旋律(后缀数组+单调队列)

    #1403 : 后缀数组一·重复旋律 时间限制:5000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成 ...

  4. 【HIHOCODER 1403】后缀数组一·重复旋律(后缀数组)

    描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为长度为 N 的数构成的数列. 小Hi在练习过很多曲子以后发现很多作品自身包含一样的旋律.旋律是一段连续的数列,相似的旋律在原数列 ...

  5. HihoCoder 重复旋律

    あの旋律を何度も繰り返しでも.あの日見た光景を再現できない 无论将那段旋律重复多少次,也无法重现那一日我们看到的景象 もし切ないならば.時をまきもどしてみるかい? 若是感到惆怅的话,要试着让时光倒流吗 ...

  6. 【后缀自动机】hihocoder1445 后缀自动机二·重复旋律5

    解题方法提示 小Hi:本周的题目其实就是给定一个字符串S,要求出S的所有不同子串的数目.小Ho你知道如何快速求解么? 小Ho:我们最近在讨论后缀自动机,所以肯定是和后缀自动机有关!根据上周学习的SAM ...

  7. hihocoder1445 后缀自动机二·重复旋律5

    传送门:http://hihocoder.com/problemset/problem/1445 [题解] 大概看了一天的后缀自动机,总算懂了一些 这篇文章写的非常好,诚意安利:Suffix Auto ...

  8. HihoCoder1445 后缀自动机二·重复旋律5(后缀自动机 子串种数)

    题意: 询问串的不同子串个数 思路: 后缀自动机每个节点表示以当前字符结尾的一系列后缀,个数为\(maxlen - minlen\),其中\(minlen = maxlen[father]\). 代码 ...

  9. BZOJ 后缀自动机四·重复旋律7

    后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的 ...

随机推荐

  1. MySQL数据库(8)_MySQL数据库总结

    sql语句规范 sql是Structured Query Language(结构化查询语言)的缩写.SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言. 在使用它时,只需要发出“做什么” ...

  2. Python3 optparse模块

    Python 有两个内建的模块用于处理命令行参数: 一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数: 另一个是 optparse,它功能强大 ...

  3. linux 网卡buffer大小

    参考截取一部分:https://blog.csdn.net/ysu108/article/details/7764461 在linux下可以修改协议栈改变tcp缓冲相关参数: 修改系统套接字缓冲区 e ...

  4. Shell编程之while循环和until循环

    一.当型和直到型循环 1.while循环语句 while < 条件表达式 > do 指令... done while循环执行流程对应的逻辑图 2.until循环语句 until < ...

  5. Hadoop单机搭建

    单机Hadoop搭建 1.下载hadoop-2.7.3.tar.gz http://www.apache.org/dyn/closer.cgi/hadoop/common/hadoop-2.7.3/h ...

  6. 获取CPU利用率

    #define MB (1024 * 1024) MEMORYSTATUSEX statex; statex.dwLength = sizeof (statex); GlobalMemoryStatu ...

  7. oracle创建表空间 扩展表空间文件 修改表空间自动增长

    1. 创建表空间 create tablespace SIRM2  datafile 'D:\oracle\product\10.2.0\oradata\orcl\SIRM2.dbf' size 10 ...

  8. 山东省第六届ACM省赛 H---Square Number 【思考】

    题目描述 In mathematics, a square number is an integer that is the square of an integer. In other words, ...

  9. Springmvc跳转路径

    forward转发地址栏不发生变化,redirect跳转地址栏变化,forward能把request域中的参数带给下一个,而redirect不会带过去,但是Springmvc的model虽然是基于re ...

  10. Elasticsearch 存储模型