先求个SAM,然后再每个后缀的对应点上标记si[nw]=1,造好SAM之后用吧parent树建出来把si传上去,然后用si[u]更新f[max(u)],最后用j>i的[j]更新f[i]

因为每个点u对应长为min(u)~max(u)的串,我们就把它记在max(u)上,最后再统一向前更新,然后更新后的si就表示right大小,也就是这个串对应的后缀个数

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1000005;
int n,fa[N],ch[N][27],dis[N],si[N],cur=1,con=1,la,h[N],cnt,f[N];
char s[N];
struct qwe
{
int ne,to;
}e[N<<2];
void add(int u,int v)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
h[u]=cnt;
}
void ins(int c,int id)
{
la=cur,dis[cur=++con]=id,si[cur]=1;
int p=la;
for(;p&&!ch[p][c];p=fa[p])
ch[p][c]=cur;
if(!p)
fa[cur]=1;
else
{
int q=ch[p][c];
if(dis[q]==dis[p]+1)
fa[cur]=q;
else
{
int nq=++con;
dis[nq]=dis[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[q]=fa[cur]=nq;
for(;ch[p][c]==q;p=fa[p])
ch[p][c]=nq;
}
}
}
void dfs(int u)
{
for(int i=h[u];i;i=e[i].ne)
{
dfs(e[i].to);
si[u]+=si[e[i].to];
}
f[dis[u]]=max(f[dis[u]],si[u]);
}
int main()
{
scanf("%s",s+1);
n=strlen(s+1);
for(int i=1;i<=n;i++)
ins(s[i]-'a',i);
for(int i=2;i<=con;i++)
add(fa[i],i);
dfs(1);
for(int i=n-1;i>=1;i--)
f[i]=max(f[i],f[i+1]);
for(int i=1;i<=n;i++)
printf("%d\n",f[i]);
return 0;
}

spoj NSUBSTR - Substrings【SAM】的更多相关文章

  1. 【SAM】codevs3160-最长公共子串

    [题目大意] 求两个字符串的最长公共子串. [思路] 对第一个字符串建立后缀自动机,第二个字符串去匹配.cnt记录当前最长公共子串的长度,而ret记录答案. p代表位置指针,初始在rt位置. 对于第二 ...

  2. 【SAM】BZOJ2882-工艺

    [题目大意] 求一个循环数列的最小表示法. [思路] 最小表示法的正解:★ SAM乱搞,和前面的POJ那道一样.然而MLE了,当作学习一下map的用法^ ^ map的使用方法(来源:☆) 一.map的 ...

  3. 【SAM】BZOJ3998-弦论

    [题目大意] 给出一个字符串,求第k大的子串.(输入1表示子串可重复,0表示不可重复) [思路] 显然,k大子串是后缀自动机的经典题型,可以利用后缀自动机的性质来解决.对于字符串 [前铺1]" ...

  4. 【SAM】POJ1509-Glass Beads

    [题目大意] 求一个循环数列的最小表示法. [思路] 把原创复制一遍放在后面,建立SAM,从s按字典序开始跑长度L即可. 板子来源(作者见连接内):

  5. spoj SUBST1 - New Distinct Substrings【SAM||SA】

    SAM里的转台不会有重复串,所以答案就是每个right集合所代表的串个数的和 #include<iostream> #include<cstdio> #include<c ...

  6. SPOJ Distinct Substrings【后缀数组】

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  7. 【SPOJ - LCS2】Longest Common Substring II【SAM】

    题意 求出多个串的最长公共子串. 分析 刚学SAM想做这个题的话最好先去做一下那道codevs3160.求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长 ...

  8. spoj LCS2 - Longest Common Substring II && LCS - Longest Common Substring【SAM】

    多串LCS很适合SA但是我要学SAM 对第一个串求SAM,然后把剩下的串在SAM上跑,也就是维护p和len,到一个点,如果有ch[p][c],就p=ch[p][c],len++,否则向fa找最下的有c ...

  9. spoj SUBLEX - Lexicographical Substring Search【SAM】

    先求出SAM,然后考虑定义,点u是一个right集合,代表了长为dis[son]+1~dis[u]的串,然后根据有向边转移是添加一个字符,所以可以根据这个预处理出si[u],表示串u后加字符能有几个本 ...

随机推荐

  1. centos7 网络不能重启问题 解决办法

    cnetos7 网络不可重启 突然解决办法 参考他人处理 之前部署hadoop环境,在自己机器上安装了一台centos虚拟机,然后图省事,就克隆出三台,一台为master,另两台来作为 slave. ...

  2. HDOJ 1217 Arbitrage(拟最短路,floyd算法)

    Arbitrage Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total ...

  3. Redis java使用

    直接应用redis.clients:jedis的jar包到项目中,然后直接就可以使用,具体对五种类型的数据操作方法,可以翻代码找到. 连接到 redis 服务 实例 import redis.clie ...

  4. mysqld与mysqld_safe的区别

    文章1: 直接运行mysqld程序来启动MySQL服务的方法很少见,mysqld_safe脚本会在启动MySQL服务器后继续监控其运行情况,并在其死机时重新启动它.用mysqld_safe脚本来启动M ...

  5. python 爬虫1 開始,先拿新浪微博開始

    刚刚開始学. 目的地是两个.一个微博,一个贴吧 存入的话,临时还没想那么多.先存到本地目录吧 分词和推荐后面在整合 mysql mongodb hadoop redius 后面在用 我最终知道为什么大 ...

  6. scala快速学习笔记(三):Collections,包

    VI.Collections 1.Array 一些常用方法:println,  map( _ * 2), filter(_ % 2 == 0),  sum,   reserve Array是不可变的, ...

  7. HDOJ--1869--六度分离(用三种算法写的,希望能比較出来他们之间的差别)

    六度分离 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  8. Mac版的idea部分按钮失效的解决方案

    问题描述:调整了一下idea中jdk的路径,之后idea就无法打开新项目了,最好发现idea中的顶部菜单全部失效 解决过程: 1.把idea的jdk的路径调回去,无效 2.重启idea,无效 3.重启 ...

  9. Struts2的运行流程及其工作原理

    1 服务开启,配置文件初始化 2 用户访问login请求 3 进入web.xml文件中我们配置的核心控制器(filter) 4 核心过滤器中有一个FilterDispatcher,FilterDisp ...

  10. db_create_file_dest

    <span><span>RAC中.将db_create_file_dest改动为本地路径,在创建表空间指定ASM磁盘组的时候还能够直接'+DATA'么?</span> ...