题面

Description

给长度为 n 的字符串 S , 对任意的 L , 求长度为 L 的子串最多出现的次数.

Input

String S consists of at most 250000 lowercase latin letters.

Output

Output |S| lines. On the i-th line output F(i).

Sample Input

ababa
Sample Output
3
2
2
1
1

题解

后缀自动机统计子串出现次数的应用.

考虑我们插入一个节点时, 其suffix link上的所有节点所代表的字符串的出现次数都+1, 因此parent tree上一个节点所代表的字符串的出现次数等于以它为根的子树中实点的出现次数.

线段树上成段更新来维护即可.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector> const int LEN = 250000; struct segmentTree
{
int a[LEN << 2]; inline segmentTree()
{
memset(a, 0, sizeof(a));
} void modify(int u, int curL, int curR, int L, int R, int w)
{
if(curL >= L && curR <= R)
{
a[u] = std::max(a[u], w);
return;
}
int mid = curL + curR >> 1;
if(L <= mid)
modify(u << 1, curL, mid, L, R, w);
if(R > mid)
modify(u << 1 | 1, mid + 1, curR, L, R, w);
} inline void modify(int L, int R, int w)
{
modify(1, 1, LEN, L, R, w);
} int query(int u, int L, int R, int pos)
{
if(L == R)
return a[u];
int mid = L + R >> 1;
if(pos <= mid)
return std::max(a[u], query(u << 1, L, mid, pos));
else
return std::max(a[u], query(u << 1 | 1, mid + 1, R, pos));
} inline int query(int pos)
{
return query(1, 1, LEN, pos);
}
}sgt; struct suffixAutomaton
{
struct state
{
state *suc[26], *pre;
std::vector<state*> sucOnTr;
int len, sz, tg; inline state()
{
for(int i = 0; i < 26; ++ i)
suc[i] = NULL;
sucOnTr.clear();
sz = tg = 0;
}
}; state *rt, *lst; inline void insert(int c)
{
state *u = new state;
u->len = lst->len + 1;
u->sz = 1;
for(; lst != NULL && lst->suc[c] == NULL; lst->suc[c] = u, lst = lst->pre);
if(lst == NULL)
u->pre = rt;
else
{
state *p = lst->suc[c];
if(p->len == lst->len + 1)
u->pre = p;
else
{
state *q = new state;
*q = *p;
q->sz = 0;
q->len = lst->len + 1;
p->pre = u->pre = q;
for(; lst != NULL && lst->suc[c] == p; lst->suc[c] = q, lst = lst->pre);
}
}
lst = u;
} inline void build(char *str, int len)
{
lst = rt = new state;
rt->len = 0, rt->pre = NULL;
for(int i = 0; i < len; ++ i)
insert(str[i] - 'a');
} void getSucessorOnSuffixTree(state *u)
{
u->tg = 1;
if(u->pre != NULL)
u->pre->sucOnTr.push_back(u);
for(int i = 0; i < 26; ++ i)
if(u->suc[i] != NULL && ! u->suc[i]->tg)
getSucessorOnSuffixTree(u->suc[i]);
} void DFS(state *u)
{
for(std::vector<state*>::iterator p = u->sucOnTr.begin(); p != u->sucOnTr.end(); ++ p)
DFS(*p), u->sz += (*p)->sz;
if(u != rt)
sgt.modify(u->pre->len + 1, u->len, u->sz);
} inline void work()
{
getSucessorOnSuffixTree(rt);
DFS(rt);
}
}SAM; int main()
{
#ifndef ONLINE_JUDGE
freopen("SPOJ8222.in", "r", stdin);
#endif
static char str[LEN];
scanf("%s", str);
int len = strlen(str);
SAM.build(str, len);
SAM.work();
for(int i = 1; i <= len; ++ i)
printf("%d\n", sgt.query(i));
}

SPOJ 8222 Substrings的更多相关文章

  1. spoj 8222 Substrings (后缀自动机)

    spoj 8222 Substrings 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length(S)) 解题思路:我们构造S的SAM,那么对于 ...

  2. SPOJ 8222 Substrings(后缀自动机)

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

  3. spoj 8222 Substrings(后缀自动机+DP)

    [题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28005 [题意] 给一个字符串S,令F(x)表示S的所有长度为 ...

  4. SPOJ 8222. Substrings(后缀自动机模板)

    后缀自动机+dp. 后缀自动机主要是在functioner大牛那里学习的:http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html 这道题是在No_st ...

  5. 【SPOJ】Substrings(后缀自动机)

    [SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...

  6. 【SPOJ 8222】Substrings

    http://www.spoj.com/problems/NSUBSTR/ clj课件里的例题 用结构体+指针写完模板后发现要访问所有的节点,改成数组会更方便些..于是改成了数组... 这道题重点是求 ...

  7. ●SPOJ 8222 NSUBSTR–Substrings

    题链: http://www.spoj.com/problems/NSUBSTR/题解: 后缀自动机. 不难发现,对于自动机里面的一个状态s, 如果其允许的最大长度为maxs[s],其right集合的 ...

  8. ●SPOJ 8222 NSUBSTR - Substrings(后缀数组)

    题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然 ...

  9. ●SPOJ 8222 NSUBSTR–Substrings(后缀自动机)

    题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 后缀自动机的水好深啊!懂不了相关证明,带着结论把这个题做了.看来这滩深水要以后再来了. 本题要用到一个叫 R ...

随机推荐

  1. Wannafly挑战赛21 机器人

    从前在月球上有一个机器人.月球可以看作一个 n*m 的网格图,每个格子有三种可能:空地,障碍,机器人(有且仅有一个),现在地面指挥中心想让机器人在月球上行走,每次可以发送一个指令,为 U-往上走.D- ...

  2. Leetcode36--->Valid Sudoku(判断给定的数独是否有效)

    题目:给定一个数独,某些部分已经被填上了数字,其余空的地方用‘.’表示:判断给定的数独是否有效: 数独规则: 每一行不能有重复的数字:每一列不能有重复的数字:将数独框划分为三行三列,没9个小方格不能有 ...

  3. hiho编程练习赛20

    模版题的世界 题目1 : 无根数变有根树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一棵包含 N 个节点的无根树,小Hi想知道如果指定其中某个节点 K 为根,那 ...

  4. Jboss性能调优

    1,Jboss5调优指南 https://www.redhat.com/f/pdf/JB_JEAP5_PerformanceTuning_wp_web.pdf 1,Jboss7.1 性能调优指南 a: ...

  5. 【转】C# 中的"yield"使用

    C# 中的"yield"使用 yield是C#为了简化遍历操作实现的语法糖,我们知道如果要要某个类型支持遍历就必须要实现系统接口IEnumerable,这个接口后续实现比较繁琐要写 ...

  6. JDBC 学习笔记(四)—— JDBC 加载数据库驱动,获取数据库连接

    1. 加载数据库驱动 通常来说,JDBC 使用 Class 类的 forName() 静态方法来加载驱动,需要输入数据库驱动代表的字符串. 例如: 加载 MySQL 驱动: Class.forName ...

  7. JDBC 学习笔记(二)—— 详解 JDBC 的四种驱动类型

    JDBC 有四种驱动类型,分别是: JDBC-ODBC 桥(JDBC-ODBC bridge driver plus ODBC driver) 本地 API 驱动(Native-API partly ...

  8. How to use MJRefresh

    Installation with CocoaPods:pod 'MJRefresh' Manual import: Drag All files in the MJRefresh folder to ...

  9. 【Luogu】P3356火星探险问题(费用流)

    题目链接 网络流一条边都不能多连?没道理呀? 不过单看这题的确是个sb题…… #include<cstdio> #include<algorithm> #include< ...

  10. BZOJ3930 [CQOI2015]选数 【容斥】

    题目 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公约数,以便进一步研 ...