SPOJ 8222 Substrings
题面
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的更多相关文章
- spoj 8222 Substrings (后缀自动机)
spoj 8222 Substrings 题意:给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值.求F(1)..F(Length(S)) 解题思路:我们构造S的SAM,那么对于 ...
- SPOJ 8222 Substrings(后缀自动机)
[题目链接] http://www.spoj.com/problems/NSUBSTR/ [题目大意] 给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值. 求出所有的F. [题 ...
- spoj 8222 Substrings(后缀自动机+DP)
[题目链接] http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28005 [题意] 给一个字符串S,令F(x)表示S的所有长度为 ...
- SPOJ 8222. Substrings(后缀自动机模板)
后缀自动机+dp. 后缀自动机主要是在functioner大牛那里学习的:http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html 这道题是在No_st ...
- 【SPOJ】Substrings(后缀自动机)
[SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...
- 【SPOJ 8222】Substrings
http://www.spoj.com/problems/NSUBSTR/ clj课件里的例题 用结构体+指针写完模板后发现要访问所有的节点,改成数组会更方便些..于是改成了数组... 这道题重点是求 ...
- ●SPOJ 8222 NSUBSTR–Substrings
题链: http://www.spoj.com/problems/NSUBSTR/题解: 后缀自动机. 不难发现,对于自动机里面的一个状态s, 如果其允许的最大长度为maxs[s],其right集合的 ...
- ●SPOJ 8222 NSUBSTR - Substrings(后缀数组)
题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 同届红太阳 --WSY给出的后缀数组解法!!! 首先用倍增算法求出 sa[i],rak[i],hei[i]然 ...
- ●SPOJ 8222 NSUBSTR–Substrings(后缀自动机)
题链: http://www.spoj.com/problems/NSUBSTR/ 题解: 后缀自动机的水好深啊!懂不了相关证明,带着结论把这个题做了.看来这滩深水要以后再来了. 本题要用到一个叫 R ...
随机推荐
- F查询与Q查询
F查询 如果我们要对两个字段的值做比较,那该怎么做呢? Django 提供 F() 来做这样的比较.F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值. # 查询评论 ...
- PTA 7-1 银行业务队列简单模拟
用链表实现队列操作,代码如下: #include <iostream> #include <cstdio> #include <algorithm> #includ ...
- flask-用户资料
首先创建User模型 class User(UserMixin,db.Model): __tablename__ = 'users' #.. name = db.Column(db.String(64 ...
- foreach遍历数组的表格
<?php /** * * @authors Your Name (you@example.org) * @date 2017-03-17 19:06:19 * @version $Id$ */ ...
- while循环输出的表格
方法一: <?php echo '<table border="1" width="800" align="center"> ...
- POJ - 1321 深度优先搜索入门
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> us ...
- C++智能指针实现
#include <iostream> #include <string> #define unsigned int size_t using namespace std; / ...
- [转] immutability-helper 插件的基本使用(附源码)
概念 先理解一下 Immutable 的概念,Immutable数据就是一旦创建,就不能更改的数据.每当对Immutable对象进行修改的时候,就会返回一个新的Immutable对象,以此来保证数据的 ...
- luogu2763 试题库问题
倘若某个试题已经被选到某个类型里了,那么它就不可再被选进别的类型了. 所以,对于每个类型,我们将其与汇连边,权值是它的要求的题目数量. 对于每个题目,我们将源与其连边,权值是1,代表只能用一次.然后再 ...
- bat 中的特殊符号输出问题
系统关键字(感叹号!)冲突 由于是自动化部署,因此需要使用到循环,这里就不可避免的用到了延迟变量(setlocal enabledelayedexpansion) 有关延迟变量的知识,大家可以通过这篇 ...