SPOJ NSUBSTR 求每个对应的长度能产生的相同子串的最大个数
来源:互联网 发布:linux .ac文件 编辑:程序博客网 时间:2024/06/05 03:16
You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as the maximal number of times that some string with length x appears in S. For example for string ‘ababa’ F(3) will be 2 because there is a string ‘aba’ that occurs twice. Your task is to output F(i) for every i so that 1<=i<=|S|.
Input
String S consists of at most 250000 lowercase latin letters.
Output
Output |S| lines. On the i-th line output F(i).
Example
Input:
ababa
Output:
3
2
2
1
1
给定一个字符串,求每个对应的长度能产生的相同子串的最大个数
后缀自动机 首先要得出所有长度的子串在总串中的出现次数,其实只要得出最大长度就好,其他的长度可以由 dp[len]=max(dp[len],dp[len+1]) 得到。
后缀自动机上每个节点代表可以接收的最大长度后缀。那么可以 利用子节点往父节点更新就好。因为子节点出现的地方父节点也必然会出现,最后扫一遍len就行
#include <bits/stdc++.h>using namespace std;const int maxn = 500000+5;int last,tail,Min[maxn];int Max[maxn],cnt[maxn],vis[maxn];int nxt[maxn][26],fail[maxn];char sa[maxn],sb[maxn];int Maxi[maxn];int sz[maxn];int b[maxn];inline void build(char *s){ while(*s) { int p=last,t=++tail,c=*s++-'a'; sz[t]=1; Max[t]=Max[p]+1; while(p&&!nxt[p][c]) nxt[p][c]=t,p=fail[p]; if(p) { int q=nxt[p][c]; if(Max[q]==Max[p]+1) fail[t]=q,Min[t]=Max[q]+1; else { int k=++tail; fail[k]=fail[q]; fail[t]=fail[q]=k; Max[k]=Max[p]+1; memcpy(nxt[k],nxt[q],sizeof(nxt[q])); while(p&&nxt[p][c]==q) nxt[p][c]=k,p=fail[p]; } } else fail[t]=Min[t]=1; last=t; }}int q[maxn];int f[maxn];int main(){ scanf("%s",sa); last=1,tail=1; build(sa); int len=strlen(sa); for(int i=1;i<=tail;i++) cnt[Max[i]]++; for(int i=1;i<=len;i++) cnt[i]+=cnt[i-1]; for(int i=1;i<=tail;i++) b[cnt[Max[i]]--]=i; for(int i=tail;i>=1;i--) sz[fail[b[i]]]+=sz[b[i]]; for(int i=1;i<=tail;i++) f[Max[i]]=max(f[Max[i]],sz[i]); for(int i=len;i>=1;i--) f[i]=max(f[i],f[i+1]); for(int i=1;i<=len;i++) printf("%d\n",f[i] );}
阅读全文
0 0
- SPOJ NSUBSTR 求每个对应的长度能产生的相同子串的最大个数
- SPOJ - DISUBSTR Distinct Substrings(后缀数组求不相同的子串个数)
- spoj 694 求一个字符串中不相同子串的个数
- spoj 694 不相同的子串的个数
- SPOJ 694,705(不相同的子串个数)
- SPOJ 694 / SPOJ DISUBSTR Distinct Substrings【后缀数组】不相同的子串的个数
- 求最大回文子串的长度
- spoj 694 求不同子串的个数
- spoj705( 求不相同的子串个数)
- spoj 694 OR 705 不相同的子串的个数
- spoj 694 Distinct Substrings(不相同的子串的个数)
- SPOJ 694. Distinct Substrings (不相同的子串的个数--后缀数组)
- SPOJ DISUBSTR - Distinct Substrings(后缀数组[不相同的子串的个数])
- SPOJ SUBST1 - New Distinct Substrings(后缀数组[不相同的子串的个数])
- 后缀数组(不相同的子串个数)——SPOJ 705
- 求两字符串的最大相同子串--JAVA实现
- 求两个字符串的最大相同子串
- 求任意两个字符串的最大相同子串
- 剑指offer--删除链表中重复的结点
- HDU-1242-Rescue
- Python3.5学习笔记(1)-Python基础
- 自动化测试输入文字
- C++风格_模板编程
- SPOJ NSUBSTR 求每个对应的长度能产生的相同子串的最大个数
- c++内联函数
- uva-1349 Optimal Bus Route Design(最小费用最大流)
- print >>
- 成员变量局部变量和静态变量的区别
- 走进Python
- 鼠标滑轮事件监听
- captcha和recapcha
- 类