后缀自动机 重复旋律 5(求所有本质不同的子串)
2017-10-03 13:23
423 查看
后缀自动机二 重复旋律五
本题要求我们求出一个字符串S中本质不同的子串个数。
显然,答案就是所有状态上的子串个数之和,这里说的一个状态上的子串个数,是longest-shortest+1。主要需要学习的是,后缀自动机的O(N)构建方法。需要了解的是,一个状态u的shortest=fail.longest+1。
本题要求我们求出一个字符串S中本质不同的子串个数。
显然,答案就是所有状态上的子串个数之和,这里说的一个状态上的子串个数,是longest-shortest+1。主要需要学习的是,后缀自动机的O(N)构建方法。需要了解的是,一个状态u的shortest=fail.longest+1。
#include <bits/stdc++.h> using namespace std; const int mxn = 2000100; namespace suffixAuttomaton{ int tail=2; int fail[mxn]; int maxi[mxn]; int mini[mxn]; int next[mxn][26]; inline int extend(int p,int c) { int t=tail++; maxi[t]=maxi[p]+1; while(p&&!next[p][c]) next[p][c]=t,p=fail[p]; if(p) { int q=next[p][c]; if(maxi[q]==maxi[p]+1) fail[t]=q,mini[t]=maxi[q]+1; else { int k=tail++; fail[k]=fail[q]; fail[q]=fail[t]=k; maxi[k]=maxi[p]+1; mini[q]=maxi[k]+1; mini[t]=maxi[k]+1; for(int i=0;i<26;i++) next[k][i]=next[q][i]; while(p&&next[p][c]==q) next[p][c]=k,p=fail[p]; mini[k]=maxi[fail[k]]+1; } } else fail[t]=1,mini[t]=1; return t; } } using namespace suffixAuttomaton; int n; char s[mxn]; int main() { scanf("%s",s); n=strlen(s); int last=1; for(int i=0;i<n;i++) last=extend(last,s[i]-'a'); long long ans=0; for(int i=2;i<tail;i++) ans+=maxi[i]-mini[i]+1; printf("%lld\n",ans ); }
相关文章推荐
- 后缀自动机 重复旋律 7 求所有不同的子串的值的总和
- 若干的数字串所有不同子串的和 后缀自动机
- HDU 4641 至少出现K次本质不同子串数:后缀自动机
- hiho一下第131周 后缀自动机二·重复旋律8(循环相似子串)
- hihoCoder 后缀自动机三·重复旋律6
- hiho一下第128周 后缀自动机二·重复旋律5
- hihocoder #1445 : 后缀自动机二·重复旋律5
- HDU 4622 Reincarnation(SAM 后缀自动机 求子串的不同子串个数)
- HihoCoder1445 重复旋律5(后缀自动机)
- hihocoder 1445 : 后缀自动机二·重复旋律5(后缀自动机)
- hihocoder #1449 : 后缀自动机三·重复旋律6
- HihoCoder - 1445 后缀自动机二·重复旋律5 后缀自动机
- Hiho 122 后缀数组三·重复旋律3(多个串的最长公共重复子串)
- hihocoder #1457 : 后缀自动机四·重复旋律7
- hihocoder #1465 : 后缀自动机五·重复旋律8
- HihoCoder - 1449 后缀自动机三·重复旋律6 后缀自动机、递推、DFS
- 后缀自动机(不同子串的个数)hdu4416
- 【后缀自动机】【拓扑排序】【动态规划】hihocoder1457 后缀自动机四·重复旋律7
- 【hihoCoder 1466】后缀自动机六·重复旋律9
- hiho一下第130周 后缀自动机二·重复旋律7