[SAM] hihoCoder1445 后缀自动机二·重复旋律5
2017-07-26 23:05
399 查看
题意
给出一个只含小写字母的串 s ,求 s 的不同的子串总数。|s|≤1000000
题解
SAM 最水的模板题。直接建出 SAM ,把所有状态的 max(A)−min(A)+1 全部加起来即是答案。应该不需要解释。
实现的话可以在 Extend 过程中维护,这样写比较有价值,最后扫一趟太丑啦…
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=1000005; struct node{ node *par,*ch[26]; int _max; node(int t1=0){ _max=t1; par=0; memset(ch,0,sizeof(ch)); } int cnt(){ return _max-par->_max; } } *root, *last; typedef node* P_node; long long ans; void Extend(char x){ P_node p=last, np=new node(p->_max+1); while(p&&p->ch[x]==0) p->ch[x]=np, p=p->par; if(!p) np->par=root; else{ P_node q=p->ch[x]; if(q->_max==p->_max+1) np->par=q; else{ P_node nq=new node(p->_max+1); memcpy(nq->ch,q->ch,sizeof(q->ch)); ans-=q->cnt(); //* nq->par=q->par; q->par=nq; np->par=nq; ans+=q->cnt()+nq->cnt(); //* while(p&&p->ch[x]==q) p->ch[x]=nq, p=p->par; } } ans+=np->cnt(); //* last=np; } char s[maxn]; int n; int main(){ freopen("hiho1445.in","r",stdin); freopen("hiho1445.out","w",stdout); scanf("%s",s+1); n=strlen(s+1); root=last=new node(0); for(int i=1;i<=n;i++) Extend(s[i]-'a'); printf("%lld\n",ans); return 0; }
相关文章推荐
- hihocoder 1445 : 后缀自动机二·重复旋律5(后缀自动机)
- 【后缀自动机】hihocoder1445 后缀自动机二·重复旋律5
- HihoCoder - 1445 后缀自动机二·重复旋律5 后缀自动机
- HihoCoder1445 重复旋律5(后缀自动机)
- 【hihocoder1445】后缀自动机二·重复旋律5 后缀自动机模板
- 【hihoCoder 1466】后缀自动机六·重复旋律9
- hihocoder #1445 : 后缀自动机二·重复旋律5
- hihocoder #1445 : 后缀自动机二·重复旋律5
- HihoCoder1465 重复旋律8(后缀自动机)
- hihoCoder #1445 : 后缀自动机二·重复旋律5
- hihoCoder 后缀自动机三·重复旋律6
- 【后缀自动机】hihocoder1449 后缀自动机三·重复旋律6
- HihoCoder - 1449 后缀自动机三·重复旋律6 后缀自动机、递推、DFS
- 【后缀自动机】【拓扑排序】【动态规划】hihocoder1457 后缀自动机四·重复旋律7
- hihoCoder.1457.后缀自动机四 重复旋律7(广义后缀自动机)
- HihoCoder - 1457 后缀自动机四·重复旋律7 后缀自动机+拓扑排序+递推、BFS
- HihoCoder1449 重复旋律6(后缀自动机)
- hihoCoder.1465.后缀自动机五 重复旋律8(后缀自动机)
- 【hihocoder1457】后缀自动机四·重复旋律7 后缀自动机
- hihoCoder 1415 后缀数组三·重复旋律3(最长公共子串)