重复旋律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. facebook开源了他们的分布式大数据DB

    https://github.com/facebook/presto facebook 3天前开源了他们的 分布式大数据DB Distributed SQL query engine for big ...

  2. first application

    <!DOCTYPE html> <html> <head> <title>Create a Map</title> <meta htt ...

  3. hadoop04---shell

    Linux上的mysql安装之后卸载是卸载不干净的,ping服务器ping不通就是把icmp协议关闭了,ping使用的是icmp协议. Export是全局变量,所有用户登录进来都可以使用. 1.ipt ...

  4. Docker容器技术-在开发中引用Docker

    明确一点: 容器不适合构建那种发布周期以周或月为单位的大型单一架构企业软件,容器适合采用微服务的方式,以及探索诸如持续部署这样的技术,使得我们能安全地在一天内多次更新生产环境. 一.在开发中引用Doc ...

  5. webstrom上运行node项目配置操作

    其实特别简单.... 去webtrom主界面找到下图的按钮,点击 点击之后弹框如下: 点击左上方绿色加号,如下图,点击node.js 点击之后,填写下图中内容: 点击应用,主界面的绿色开始按钮就可以用 ...

  6. canvas 视频音乐播放器

    canvas 视频音乐播放器 var play_nor_img_path = 'images/play_btn_n.png'; //播放按钮 正常时 60x60 px var play_sec_img ...

  7. 八、golang文本操作、json协议

    一.终端读写 操作终端相关文件语句常量,go所有的都是接口 os.Stdin:标准输入 os.Stdout:标准输入,只要实现输出这个接口,打印到终端, os.Stderr:标准错误输出 os.Ope ...

  8. HDU 4348 To the moon (主席树区间更新)

    题意:首先给你n个数,开始时间为0,最后按照操作输出 给你四种操作: 1. C l r d :  在(l,r)区间都加上d,时间加一2. Q l r :  询问现在(l,r)的区间和3. H l r ...

  9. script标签加载js代码的一些知识

    1.script加载js代码是并行加载,顺序执行的,并且在加载和执行js时会阻塞浏览器渲染引擎, 2.defer和async属性添加过后,js的下载和执行就不会阻塞浏览器的渲染引擎了 3.defer会 ...

  10. js数字过大js自动变0

    解决方案: <a onclick="checkDate(${item.billday},'${item.bankcard}',${item.limitmoney/100}) 加上引号变 ...