SPOJ8222 NSUBSTR - Substrings
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!
题目链接:SPOJ8222
正解:后缀自动机
解题报告:
我好菜啊,现在才学SAM…
大概的构造就是在线的增量法,看看代码还是挺好懂的,简洁明了…
有几个基础性质:自动机上的每个点上代表的字符串集合的右端点相同,$right$集合相同。
而且两个点的$right$集合要么是包含关系,要么就不相交。
每个节点的控制范围就是$(maxs_{fa},maxs_u]$,这样就不用维护自身的$mins$了,比较方便。
儿子节点的$right$集合是父状态的子集,在$parent$树上往上走相当于砍掉了一个前缀。
根据前面的性质,$|right_{fa}|= \sum {|right_u|}$,那么这道题就能做了…
自下往上搞出每个点的$right$集合大小,用集合大小去更新$maxs$的$ans$就可以了。
要用基数排序。
//It is made by ljh2000
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <complex>
#include <bitset>
using namespace std;
typedef long long LL;
typedef long double LB;
typedef complex<double> C;
const double pi = acos(-1);
const int MAXN = 500011;
int n,last,S,cnt,a[MAXN],ch[MAXN][26],len[MAXN],fa[MAXN],ans[MAXN];
int tong[MAXN],sa[MAXN],R[MAXN],f[MAXN];
char s[MAXN]; inline int getint(){
int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
} inline void add(int x){
int c=a[x]; int p=last,np=++cnt; last=np;
len[np]=x; for(;p && !ch[p][c];p=fa[p]) ch[p][c]=np;
if(!p) fa[np]=S;
else {
int q=ch[p][c];
if(len[q]==len[p]+1) fa[np]=q;
else {//不满足SAM上每个节点关于right集合的性质,拆成两个来分别接收
int nq=++cnt; len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for(;ch[p][c]==q;p=fa[p]) ch[p][c]=nq;//把对应的走到q的边全改成走到nq
}
}
} inline void work(){
scanf("%s",s+1); n=strlen(s+1);
S=last=++cnt; for(int i=1;i<=n;i++) a[i]=s[i]-'a';
for(int i=1;i<=n;i++) add(i);
for(int i=1,p=S;i<=n;i++) p=ch[p][a[i]],R[p]++;//主链上的right集合初值设为1
for(int i=1;i<=cnt;i++) tong[ len[i] ]++;
for(int i=1;i<=n;i++) tong[i]+=tong[i-1];
for(int i=1;i<=cnt;i++) sa[ tong[ len[i] ] -- ]=i;
for(int i=cnt;i>=1;i--) R[ fa[ sa[i] ] ]+=R[ sa[i] ];
for(int i=1;i<=cnt;i++) f[ len[i] ]=max(f[ len[i] ],R[i]);//统计每种长度子串的最大出现次数,就是用right集合去更新maxs
for(int i=n;i>=1;i--) f[i]=max(f[i+1],f[i]);
for(int i=1;i<=n;i++) printf("%d\n",f[i]);
} int main()
{
work();
return 0;
}
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
SPOJ8222 NSUBSTR - Substrings的更多相关文章
- SPOJ8222 NSUBSTR - Substrings(后缀自动机)
You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as ...
- SPOJ8222 NSUBSTR - Substrings 后缀自动机_动态规划
讲起来不是特别好讲.总之,如果 $dp[i+1]>=dp[i]$,故$dp[i]=max(dp[i],dp[i+1])$ Code: #include <cstdio> #inclu ...
- SPOJ8222/NSUBSTR:Substrings——题解
https://www.luogu.org/problemnew/show/SP8222#sub http://www.spoj.com/problems/NSUBSTR/ 翻译来自洛谷. 你得到一个 ...
- 【spoj8222】 Substrings
http://www.spoj.com/problems/NSUBSTR/ (题目链接) 题意 给出一个字符串S,令${F(x)}$表示S的所有长度为x的子串出现次数的最大值.求${F(1)..... ...
- 【spoj8222】Substrings
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- ●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 ...
- SPOJ 8222 NSUBSTR - Substrings
http://www.spoj.com/problems/NSUBSTR/ 题意: F(x)定义为字符串S中所有长度为x的子串重复出现的最大次数 输出F[1]~F[len(S)] 用字符串S构建后缀自 ...
随机推荐
- Buy the souvenirs---hdu2126(01背包输出方案数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2126 有n个物品每个物品的价格是v[i],现在有m元钱问最多买多少种物品,并求出有多少种选择方法: 如 ...
- qemu网络虚拟化之数据流向分析一
插曲: 今天下午欣喜的想写点关于qemu网络部分的功能,但是中途出现了点小插曲,电脑被某人搞得死机了,并且文章也没有保存.结果,,,就只能重新写了!!所以这里强烈建议开发团队提供自动保存的功能! ...
- 【opencv入门篇】快速在VS上配置opencv
环境配置:win7-32 + opencv2.4.6 + vs2013 注意:无论电脑是32位还是64位,配置opencv库目录时选择x84文件夹!因为编译都是使用32位编译:如果选用X64,则程序运 ...
- 【开发者笔记】冒泡排序过程呈现之java内置GUI表示
自己玩玩写写,排序的过程多么有趣,特别是把看着电脑吧一堆乱七八糟的数据排成有序组合的时候,看起来贼舒服,特别是强迫症患者.好了,话不多说上代码,也算是自己记录一下吧,没有什么技术含量但个人感觉比较有趣 ...
- livego
1.安装golang开发环境 https://www.cnblogs.com/eczhou/p/7929693.html 2.livego源码及说明文档 https://github.com/zhou ...
- python学习笔记(二十七)多线程与多进程
线程是程序里面的最小执行单元. 进程是资源的集合. 线程是包含在一个进程里面,一个进程可以有多个线程,一个进程里面默认有一个主线程.由主线程去启动子线程. 1.多线程 import threading ...
- koa2简单demo
// 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示: const Koa = require('koa'); const Router = req ...
- mysql时间戳转换成可读时间格式
代码: SELECT FROM_UNIXTIME(1234567890, '%Y-%m-%d %H:%i:%S') 附:在mysql中,一个时间字段的存储类型是int(11),怎么转化成字符类型,比方 ...
- 【转】html之file标签 --- 图片上传前预览 -- FileReader
记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...
- Ubuntu14.04+caffe+cuda7.5 环境搭建以及MNIST数据集的训练与测试
Ubuntu14.04+caffe+cuda 环境搭建以及MNIST数据集的训练与测试 一.ubuntu14.04的安装: ubuntu的安装是一件十分简单的事情,这里给出一个参考教程: http:/ ...