【spoj8222】Substrings
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 500005
#define maxm 250005
using namespace std; int n,tot,root,last,f[maxm],fa[maxn],son[maxn][],dist[maxn],ri[maxn],sum[maxm],tmp[maxn];
char st[maxm];
struct Tsegment{
void prepare(){tot=root=last=; memset(dist,,sizeof(dist)); memset(sum,,sizeof(sum));}
int newnode(int x){
dist[++tot]=x; return tot;
}
void add(int x){
int p=last,np=newnode(dist[last]+); last=np;
for (;p&&!son[p][x];p=fa[p]) son[p][x]=np;
if (p==) fa[np]=root;
else{
int q=son[p][x];
if (dist[p]+==dist[q]) fa[np]=q;
else{
int nq=newnode(dist[p]+);
memcpy(son[nq],son[q],sizeof(son[q]));
fa[nq]=fa[q],fa[q]=fa[np]=nq;
for (;p&&son[p][x]==q;p=fa[p]) son[p][x]=nq;
}
}
}
}SAM; int main(){
scanf("%s",st+),n=strlen(st+);
SAM.prepare();
for (int i=;i<=n;i++) SAM.add(st[i]-'a');
last=root;
for (int i=;i<=n;i++) last=son[last][st[i]-'a'],ri[last]=;
memset(sum,,sizeof(sum));
for (int i=;i<=tot;i++) sum[dist[i]]++;
for (int i=;i<=n;i++) sum[i]+=sum[i-];
for (int i=;i<=tot;i++) tmp[sum[dist[i]]--]=i;
memset(f,,sizeof(f));
for (int i=tot;i>=;i--){
int x=tmp[i];
if (fa[x]) ri[fa[x]]+=ri[x];
}
for (int i=;i<=tot;i++) f[dist[i]]=max(f[dist[i]],ri[i]);
for (int i=n-;i>=;i--) f[i]=max(f[i],f[i+]);
for (int i=;i<=n;i++) printf("%d\n",f[i]);
return ;
}
题目链接:http://www.spoj.com/problems/NSUBSTR/
题目大意:给定一个长度为n的字符串,n<=250000,求f[i],i属于[1,n],f[i]表示在给定字符串中长度为i的子串的最多出现次数。
做法:初看此题,我也是一脸懵逼,后来发现出现次数与后缀自动机中的right集合大小有关,这题主要就是如何求right集合的大小,即该点表示的状态的右端点的个数(即出现次数),初始时我们从root开始匹配全串,途径的节点我们设其right为1,其余的节点设为0,某个节点的right就是parent树中以它为根的子树中的right值的和,一次dp即可。注解:parent树是我们记录的fa数组所构成的树,该步骤具体细节见代码。
dist表示SAM上该节点所表示的状态所能代表的最长的字符串长度,我们用right【i】去更新f【dist【i】】即可,最后用一次类似前缀和的算法,求一次后缀最值,显然,长度越小,出现次数一定不会减少。最后输出f数组即可。
后缀自动机。
【spoj8222】Substrings的更多相关文章
- 【spoj8222】 Substrings
http://www.spoj.com/problems/NSUBSTR/ (题目链接) 题意 给出一个字符串S,令${F(x)}$表示S的所有长度为x的子串出现次数的最大值.求${F(1)..... ...
- 【SPOJ8222】Substrings (后缀自动机)
题意: 给一个字符串S,令F(x)表示S的所有长度为x的子串中,出现次数的最大值. 求F(1)..F(Length(S)) Length(S) <= 250000 思路:板子中st[x]定义为r ...
- 【SPOJ】Substrings(后缀自动机)
[SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...
- 【SPOJ】Substrings
出现次数很好处理,就是 \(right/endpos\) 集合的大小 那么,直接构建 \(SAM\) 求出每个位置的\(right\)集合大小 直接更新每个节点的\(longest\)就行了 最后短的 ...
- 【POJ1226】Substrings(后缀数组,二分)
题意: n<=10,len<=100 思路: 只有一个字符串的时候特判一下 #include<cstdio> #include<cstring> #include& ...
- 【UVA10829】 L-Gap Substrings (后缀数组)
Description If a string is in the form UVU, where U is not empty, and V has exactly L characters, we ...
- 【POJ3415】 Common Substrings(后缀数组|SAM)
Common Substrings Description A substring of a string T is defined as: T(i, k)=TiTi+1...Ti+k-1, 1≤i≤ ...
- 【SPOJ】Distinct Substrings(后缀自动机)
[SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/e ...
- 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)
[SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...
随机推荐
- Basic: Fisher's transform
来源:http://bbs.chinahrd.net/thread-709742-1-1.html,Kenneth的回答. z = 0.5 * ln [ (1+r)/(1-r) ]" C0 ...
- java多线程系类:基础篇:01基本概念:
这个系类的内容全部来源于http://www.cnblogs.com/skywang12345/p/3479024.html.特别在此声明!!! 本来想直接看那位作家的博客的,但还是复制过来. 多线程 ...
- .htaccess重命名时提示必须键入文件名怎么解决
在上一篇文章中提到过“目前data.uploads有执行.php权限,非常危险,需要立即取消目录的执行权限!”的时候可以通过创建一个名字为“.htaccess”的文件夹解决.但是在创建的时候却发现对记 ...
- SQL GETDATE()日期格式化函数
Sql Server 中一个非常强大的日期格式化函数 Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AMSelect CONV ...
- IE8和W3C标准下IFRAME刷新和URL的区别
一个页面中包含了一个iframe,我们要刷新这个iframe的情况 url在IE8和W3C以及IE11的区别如下: URL使用相对路径,绝对路径比如http://localhost:5568/替换成I ...
- 建立mvc过程
1.public class dbContext:Dbcontext { private readonly static string CONNECTION_STRING="name=d ...
- youtube下载
http://jingyan.baidu.com/article/39810a23d2deb2b637fda66c.html
- React Native中设计主题机制
昨天和同事讨论组件隔离性的时候讨论到关于默认样式的问题:很多情况下我们希望能够把组件设计为通用的,然后在具体项目中给他们指定一些通用的样式,譬如:背景颜色.默认字体等等.这听起来在CSS下运作起来就很 ...
- 基于VirtualBox安装Ubuntu图文教程
基于VirtualBox虚拟机安装Ubuntu图文教程 一. 下载安装VirtualBox 官网下载VirtualBox,目前版本:VirtualBox 5.1.8 for Windows hosts ...
- Oracle On 、Where、Having 区别
ON .WHERE.HAVING都能通过限制条件筛选数据,但他们的使用及其不同.下面我们来分析三者之间的区别. 1. ON 和WHERE 所有的查询都回产生一个中间临时报表,查询结果就是从返回临时报表 ...