[51nod 1292]字符串中的最大值V2
2016-08-18 11:31
316 查看
题目大意
求字符串中子串长度*出现次数的最大值模板题
没什么好说的上个SAM然后过程中发现我有一点老是忘:
忘记计算step
要注意的:计算parent树的子树信息,那么就按照step桶排,然后倒着扫。不能直接按照编号倒着扫。
#include<cstdio> #include<algorithm> #include<cstring> #define fo(i,a,b) for(i=a;i<=b;i++) #define fd(i,a,b) for(i=a;i>=b;i--) using namespace std; typedef long long ll; const int maxn=1000000+10; char s[maxn]; int g[maxn*2][26],step[maxn*2],pre[maxn*2],size[maxn*2],cnt[maxn],a[maxn*2]; int i,j,k,l,t,n,m,tot,last; ll ans; void add(int x){ int np=++tot,p=last; step[np]=step[p]+1; while (p>=0&&g[p][x]==0) { g[p][x]=np; p=pre[p]; } if (p==-1) pre[np]=0; else{ int q=g[p][x]; if (step[q]==step[p]+1) pre[np]=q; else{ int nq=++tot,i; fo(i,0,25) g[nq][i]=g[q][i]; pre[nq]=pre[q]; step[nq]=step[p]+1; pre[q]=nq; pre[np]=nq; while (p>=0&&g[p][x]==q){ g[p][x]=nq; p=pre[p]; } } } last=np; } int main(){ scanf("%s",s+1); n=strlen(s+1); pre[0]=-1; fo(i,1,n){ add(s[i]-'a'); size[last]++; } fo(i,0,tot) cnt[step[i]]++; fo(i,1,n) cnt[i]+=cnt[i-1]; fo(i,0,tot) a[cnt[step[i]]--]=i; fd(i,tot+1,1) size[pre[a[i]]]+=size[a[i]]; fo(i,1,tot) ans=max(ans,(ll)size[i]*step[i]); printf("%lld\n",ans); }
相关文章推荐
- 51 nod 1292 字符串中的最大值 V2(后缀数组)
- 51nod 1277 1292字符串的最大值系列
- 51Nod 1292 字符串中的最大值 V2 后缀数组 + 单调栈
- 51Nod-1197-字符串的数量 V2
- [KMP next树] 51Nod 1277 字符串中的最大值
- 51nod 1197 字符串的数量 V2(矩阵快速幂+数论?)
- 51Nod-1277-字符串中的最大值
- 51Nod-1254-最大子段和 V2
- [51nod 1197] 字符串的数量 V2
- 51nod 1053 最大M子段和 V2 (链表 对经典dp进行优化)
- 51Nod-1188-最大公约数之和 V2
- 51nod 1277 字符串中的最大值【KMP算法】【next树】
- 2566. [51nod 1129] 字符串最大值
- 51Nod-1277-字符串中的最大值
- [51nod 1129] 字符串最大值(kmp)
- 51nod 1053 最大M子段和 V2
- 51nod 1188 最大公约数之和 V2
- kmp-51nod 1277 字符串中的最大值
- 51NOD 1277 字符串中的最大值 【拓展KMP】
- 51nod 1254 最大子段和 V2 ——单调栈