思路

显然endpos的大小就对应了对应子串的出现次数,所以快速求出endpos的大小,然后用它更新对应子串长度(minlen[i]~maxlen[i])的答案即可

endpos的大小可以拓扑排序求出,发现suflink构成了一棵树,每个点代表的串都是孩子的后缀,所以$$endpos[x]\ge\sum_{v\in son[x]}endpos[v]$$

至于为什么会大于呢,因为这个节点有可能还能接受s的一个前缀,这个子串无法从孩子处转移来,但是容易发现,只有增加的节点能接受一个前缀,分裂的节点不行,所以拓扑排序就能求出endpos的大小了

更新答案时,因为从1到n,ans不上升,所以可以每个state更新maxlen的答案,最后再倒序扫一遍

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 1000100*2;
int trans[MAXN][26],suflink[MAXN],ispre[MAXN],maxlen[MAXN],minlen[MAXN],cnt,in[MAXN],ans[MAXN],n,endpos[MAXN];
char s[MAXN];
int new_st(int _maxlen,int _minlen,int *_trans,int _suflink){
++cnt;
maxlen[cnt]=_maxlen;
minlen[cnt]=_minlen;
if(_trans)
for(int i=0;i<26;i++)
trans[cnt][i]=_trans[i];
suflink[cnt]=_suflink;
return cnt;
}
int add_len(int u,int c){
int z=new_st(maxlen[u]+1,0,NULL,0);
ispre[z]=true;
while(u&&(!trans[u][c])){
trans[u][c]=z;
u=suflink[u];
}
if(!u){
suflink[z]=1;
minlen[z]=1;
return z;
}
int v=trans[u][c];
if(maxlen[v]==maxlen[u]+1){
minlen[z]=maxlen[v]+1;
suflink[z]=v;
return z;
}
int y=new_st(maxlen[u]+1,0,trans[v],suflink[v]);
minlen[v]=minlen[z]=maxlen[y]+1;
suflink[v]=suflink[z]=y;
minlen[y]=maxlen[suflink[y]]+1;
while(u&&trans[u][c]==v){
trans[u][c]=y;
u=suflink[u];
}
return z;
}
queue<int> q;
int main(){
scanf("%s",s+1);
n=strlen(s+1);
int pre=1;
cnt=1;
for(int i=1;i<=n;i++)
pre=add_len(pre,s[i]-'a');
for(int i=1;i<=cnt;i++)
in[suflink[i]]++;
for(int i=1;i<=cnt;i++)
if(!in[i])
q.push(i);
while(!q.empty()){
int x=q.front();
q.pop();
endpos[x]+=ispre[x];
endpos[suflink[x]]+=endpos[x];
in[suflink[x]]--;
if(!in[suflink[x]])
q.push(suflink[x]);
}
for(int i=1;i<=cnt;i++)
ans[maxlen[i]]=max(ans[maxlen[i]],endpos[i]);
for(int i=n-1;i>=1;i--)
ans[i]=max(ans[i],ans[i+1]);
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]);
return 0;
}

HIHOcoder 1449 后缀自动机三·重复旋律6的更多相关文章

  1. hihoCoder_1449_后缀自动机三·重复旋律6

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

  2. hihoCoder 后缀自动机三·重复旋律6

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

  3. hihoCoder #1445 : 后缀自动机二·重复旋律5

    #1445 : 后缀自动机二·重复旋律5 时间限制:10000ms 单点时限:2000ms 内存限制:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一个音乐旋律被表示为一段数构成的数 ...

  4. hihocoder #1415 : 后缀数组三·重复旋律3

    #1415 : 后缀数组三·重复旋律3 Time Limit:5000ms Case Time Limit:1000ms Memory Limit:256MB 描述 小Hi平时的一大兴趣爱好就是演奏钢 ...

  5. hihoCoder #1465 : 后缀自动机五·重复旋律8

    http://hihocoder.com/problemset/problem/1465 求S的循环同构串在T中的出现次数 将串S变成SS 枚举SS的每个位置i,求出以i结尾的SS的子串 与 T的最长 ...

  6. hihocoder 1457 后缀自动机四·重复旋律7 求不同子串的和

    描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的是小Hi发现了一部名字叫<十进制进行曲大全>的作品集,顾名思义,这部作品集里有许多作品 ...

  7. HihoCoder1449 后缀自动机三·重复旋律6

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

  8. HIHOcoder 1457 后缀自动机四·重复旋律7

    思路 后缀自动机题目,题目本质上是要求求出所有不同的子串的和,SAM每个节点中存放的子串互不相同,所以对于每个节点的sum,可以发现是可以递推的,每个点对子节点贡献是sum[x]*10+c*sz[x] ...

  9. 【后缀自动机】hihocoder1449 后缀自动机三·重复旋律6

    解题方法提示 小Hi:上次我们已经学习了后缀自动机了,今天我们再来解决一个用到后缀自动机的问题. 小Ho:好!那我们开始吧! 小Hi:现在我们要对K=1..length(S)求出所有长度为K的子串中出 ...

随机推荐

  1. html5-常用的文本元素

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  2. Keras 如何利用训练好的神经网络进行预测

    分成两种情况,一种是公开的训练好的模型,下载后可以使用的,一类是自己训练的模型,需要保存下来,以备今后使用. 如果是第一种情况,则参考    http://keras-cn.readthedocs.i ...

  3. hdu4870 高斯消元

    题意 一个人打比赛 ,rating 有p的概率 为加50分 有1-p的概率为 x-100分 最大值为 1000 最小值为0 有两个号 每次拿较小的号来提交 , 计算最后到达 1000分得期望场数是多少 ...

  4. hdu5064 DLX可重复覆盖+二分

    这题题意是 给了n个城市 在其中小于等于k个城市建立机场然后 使得最远的那个离机场的城市距离最短 二分答案 ,我们对于每次的mid 重新建图然后再来一次DLX,每个点可以覆盖的点建立一条联系就ok了 ...

  5. python 安装pandas

    1.pandas有啥用 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具.pand ...

  6. Hive常用语句

    文章目录 1 显示分区 2 添加分区 3 删除分区 4 修改分区 5 添加列 6 修改列 7 修改表属性 8 表的重命名 显示分区 show partitions iteblog; 添加分区 ALTE ...

  7. C# 设置按钮快捷键

    参考自:http://www.csharpwin.com/csharpspace/3932r8132.shtml 一.C# button快捷键之第一种:Alt + *(按钮快捷键) 在Button按钮 ...

  8. bzoj1594 Pku3764 The xor-longest Path

    题目链接 先求每个点到根的异或和 然后就要找出两个点,使dis[a]^dis[b]最大 注意异或的性质,我们可以用trie树,沿着与当前数字每位的相反方向走 #include<algorithm ...

  9. Redis Windows 安装

    摘自:https://www.cnblogs.com/M-LittleBird/p/5902850.html 一.下载windows版本的Redis 去官网找了很久,发现原来在官网上可以下载的wind ...

  10. 怎样从外网访问内网Django?

    本地安装了一个Django,只能在局域网内访问,怎样从外网也能访问到本地的Django呢?本文将介绍具体的实现步骤. 准备工作 安装并启动Django 默认安装的Django端口是8000. 实现步骤 ...