题意是求一个字符串每个长度的子串出现次数最多的那个出现了多少次,也就是求每个到根的最长路的right集合最大值 。

先建后缀自动机,然后将每个前缀所在的集合的初值设为1,因为所有前缀的right集合肯定不相同,而且它们包含了所有位置。

接下来按到根的最长距离从大到小排序,将right集合累加到parent上。这么排序是因为到根的最长距离长的状态肯定不是到根的最长距离短的状态的parent。

最后直接求到根的不同的最长距离的最大的right集合就行。

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define maxn 250010
using namespace std;
int ans,len,p;
int read()
{
int f=,x=;char ch=getchar();
while(isdigit(ch)== && ch!='-')ch=getchar();
if(ch=='-')f=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();
return x*f;
}
void write(int x)
{
int ff=;char ch[];
while(x)ch[++ff]=(x%)+'',x/=;
if(ff==)putchar('');
while(ff)putchar(ch[ff--]);
putchar('\n');
}
typedef struct node
{
int to[],dis,fa;
}spot;
//求每个dis的right集合最大值
//不是每个状态的right集合!!
//ass♂we♂can♂
struct SAM
{
spot x[maxn<<];
int ls,ls2,q,cnt,rt,lst,c[maxn<<],ord[maxn<<],ans[maxn<<],maxl[maxn<<];
int right[maxn<<],f[maxn<<];
char s[maxn];
inline void start()
{
lst=rt=++cnt;
scanf("%s",s+);
ls=strlen(s+);
for(int i=;i<=ls;i++)
extend(i);
}
inline void extend(int pos)
{
int val=s[pos]-'a',p=lst,np=++cnt;
lst=np,x[np].dis=pos;
for(;p&&x[p].to[val]==;p=x[p].fa)x[p].to[val]=np;
if(p==)x[np].fa=rt;
else
{
int q=x[p].to[val];
if(x[q].dis==x[p].dis+)x[np].fa=q;
else
{
int nq=++cnt;
x[nq].dis=x[p].dis+;
memcpy(x[nq].to,x[q].to,sizeof(x[q].to));
x[nq].fa=x[q].fa,x[np].fa=x[q].fa=nq;
for(;x[p].to[val]==q;p=x[p].fa)x[p].to[val]=nq;
}
}
}
inline void qsort()
{
for(int i=;i<=cnt;i++)
c[x[i].dis]++;
for(int i=;i<=ls;i++)
c[i]+=c[i-];
for(int i=;i<=cnt;i++)
ord[c[x[i].dis]--]=i;
}
inline void work()
{
for(int i=,p=rt;i<=ls;i++)
p=x[p].to[s[i]-'a'],right[p]=;
for(int i=cnt;i>=;i--){int u=ord[i];right[x[u].fa]+=right[u];}
for(int i=;i<=cnt;i++)f[x[i].dis]=max(f[x[i].dis],right[i]);
for(int i=ls;i>=;i--)f[i]=max(f[i],f[i+]);
for(int i=;i<=ls;i++)write(f[i]);
// cout<<"He doesn't have hands->"<<endl;
}
}t;
int main()
{
t.start();
t.qsort();
t.work();
return ;
}

并不对劲的SAM

听某位大佬说后缀自动机能解决所有不是字符串dp的字符串题。

并不对劲的spoj nsubstr的更多相关文章

  1. SPOJ - NSUBSTR 后缀自动机板子

    SPOJ - NSUBSTR #include<bits/stdc++.h> #define LL long long #define fi first #define se second ...

  2. SPOJ NSUBSTR (后缀自动机)

    SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对 ...

  3. 【spoj NSUBSTR】 Substrings

    http://www.spoj.com/problems/NSUBSTR/ (题目链接) 题意 给出一个字符串S,令${F(x)}$表示S的所有长度为x的子串出现次数的最大值.求${F(1)..... ...

  4. SPOJ NSUBSTR Substrings 后缀自动机

    人生第一道后缀自动机,总是值得纪念的嘛.. 后缀自动机学了很久很久,先是看CJL的论文,看懂了很多概念,关于right集,关于pre,关于自动机的术语,关于为什么它是线性的结点,线性的连边.许多铺垫的 ...

  5. SPOJ NSUBSTR

    You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as ...

  6. SPOJ NSUBSTR Substrings

    题意 dt { font-weight: bold; margin-top: 20px; padding-left: 35px; } dd { box-shadow: 3px 3px 6px #888 ...

  7. SPOJ - NSUBSTR(长度为1-len的字串出现的最大次数

    题意:给你一个字符串,要你输出1-len的字串出现的最大次数. /** @xigua */ #include <stdio.h> #include <cmath> #inclu ...

  8. 【SPOJ -NSUBSTR】Substrings 【后缀自动机+dp】

    题意 给出一个字符串,要你找出所有长度的子串分别的最多出现次数. 分析 我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小.我们设f[len]为长度为l ...

  9. SPOJ NSUBSTR Substrings ——后缀自动机

    建后缀自动机 然后统计次数,只需要算出right集合的大小即可, 然后更新f[l[i]]和rit[i]取个max 然后根据rit集合短的一定包含长的的性质,从后往前更新一遍即可 #include &l ...

随机推荐

  1. PHP解惑(一)

    PHP给人的印象是入门简单的语言.当你的技术能力达到一定阶段时,会发现情况并非如此. PHP采用"极简主义",就是以入门容易为准则设计的,在十几年的持续发展历程中,它早已成为一个开 ...

  2. Python中的列表(3)

    我们创建的列表元素的顺序是无法预测的,因为我们无法控制用户提供数据的顺序. 为了组织列表中的元素,所以Python帮我们提供一些方法用来排序列表中的元素. 1.方法 sort() 可以对列表永久性排序 ...

  3. 4_蒙特卡罗算法求圆周率PI

    题目 蒙特卡罗算法的典型应用之一为求圆周率PI问题. 思想: 一个半径r=1的圆,其面积为:S=PI∗r2=PI/4 一个边长r=1的正方形,其面积为:S=r2=1 那么建立一个坐标系,如果均匀的向正 ...

  4. 带FIFO的UART数据接收

    芯片手册 某个Cortex-M4芯片带有1个UART,支持Tx,Rx 的FIFO功能,而且可以通过寄存器配置FIFO的阈值,芯片的datasheet并不完善,没有说明RX的FIFO具体有几个级别,每隔 ...

  5. Hdu 5274 Dylans loves tree (树链剖分模板)

    Hdu 5274 Dylans loves tree (树链剖分模板) 题目传送门 #include <queue> #include <cmath> #include < ...

  6. 19-看图理解数据结构与算法系列(Radix树)

    Radix树 Radix树,即基数树,也称压缩前缀树,是一种提供key-value存储查找的数据结构.与Trie不同的是,它对Trie树进行了空间优化,只有一个子节点的中间节点将被压缩.同样的,Rad ...

  7. CentOS7 Failed to start LSB: Bring up/down解决方法(真正有效的方法)

    刚刚装好的虚拟机突然不能上网了,报错很诡异,具体报错如下: /etc/init.d/network restart Restarting network (via systemctl):  Job f ...

  8. centos7安装mysql5.7.19及配置远程连接

    centos7安装mysql5.7.19及配置远程连接------https://blog.csdn.net/Lh19931122/article/details/77996213

  9. Bzoj3038 上帝造题的七分钟2 线段树

    Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1135  Solved: 509 Description XLk觉得<上帝造题的七分钟>不太 ...

  10. BZOJ2272: [Usaco2011 Feb]Cowlphabet 奶牛文字

    n<=250个大写字母和m<=250个小写字母,给p<=200个合法相邻字母,求用这些合法相邻字母的规则和n+m个字母能合成多少合法串,答案mod 97654321. 什么鬼膜数.. ...