题面

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. Django之用户认证

    用户认证组件简介 功能:用session记录登录验证状态 前提:必须使用django自带的auth_user表.那这里有的同学就会有疑问了,自己不能创建自己的用户表吗? 当然可以,用户认证组件虽然只针 ...

  2. R-data.table

    data.table可以扩展和增强data.frame的功能,在分组操作和组合时访问速度更快. require(data.table) theDT = data.table(A=1:10, B=let ...

  3. selenium2中TestNG相关解释

    testNg官网:http://testng.org/doc/documentation-main.html 新建testNG class的时候,同时也新建了一个TestNG.xml的文件. 此xml ...

  4. Phonegap环境配置和安装插件

    一:安装好jdk(配置好环境变量) 二:安装好Android SDK(配置好环境变量path F:\Android\android-sdk-windows\platform-tools;F:\Andr ...

  5. Ubuntu首次登入与在线求助man page总结

    1.为了避免瞬间断电造成的Linux系统的危害,建议做为服务器的Linux主机应该加上不断电系统来持续提供稳定的电力 2.默认的图形模式登入中,可以选择语系以及作业阶段.作业阶段为多种窗口管理员软件所 ...

  6. Vue简单了解

    目录 1. 前端概览 2. 现代前端开发方式 3. MVVM开发核心 4. Vue核心 5. Vue优点 6. Vue难点 7. Vue与非Vue项目结合 8. Vue调试 9. Vue与SEO 今天 ...

  7. Selenium WebDriver-通过键盘事件操作浏览器

    #encoding=utf-8 import unittest import time import chardet from selenium import webdriver class Visi ...

  8. 大数据学习——scala类相关操作

    1 类的定义 package com /** * Created by Administrator on 2019/6/3. */ //类并不用声明为public. class Person { // ...

  9. day04_01 知识回顾、算术运算符

    ","和"+"的区别 除法运算,整除//,别名"地板除" 取余数 2**10 2的10次方 指数运算 指数运算符优先级要比乘法要高,所以先算 ...

  10. linuxlinux0.11源码学习——bootsect.s学习

    由于一直想写一个自己的操作系统,网上推荐了<linux内核完全注释>.自学了一个星期,感觉这本书还是很好的,同时写下关于内核代码的理解,如果有什么不对的对方,欢迎大家一起来交流. 在内核引 ...