求不同的子串种类
Posted starve
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求不同的子串种类相关的知识,希望对你有一定的参考价值。
题:http://hihocoder.com/problemset/problem/1445
分析:后缀自动机模板
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; typedef long long ll; const int maxn=1000006; int trans[maxn<<1][26],slink[maxn<<1],maxlen[maxn<<1]; int endpos[maxn<<1]; int last,now,root,len; void init(){ now=last=root=1; memset(trans,0,sizeof(trans)); memset(maxlen,0,sizeof(maxlen)); memset(slink,0,sizeof(slink)); } void extend(int c){ maxlen[++now]=maxlen[last]+1; int p=last,np=now; while(p&&!trans[p][c]){ trans[p][c]=np; p=slink[p]; } if(!p) slink[np]=root; else{ int q=trans[p][c]; if(maxlen[p]+1!=maxlen[q]){ maxlen[++now]=maxlen[p]+1; int nq=now; memcpy(trans[nq],trans[q],sizeof(trans[q])); slink[nq]=slink[q]; slink[q]=slink[np]=nq; while(p&&trans[p][c]==q){ trans[p][c]=nq; p=slink[p]; } } else slink[np]=q; } last=np; endpos[np]=1; } ll all(){ ll ans=0; for(int i=root+1;i<=now;i++){ ans+=maxlen[i]-maxlen[slink[i]];///minlen=maxlen[slink[i]] } return ans; } int main(){ string s; init(); cin>>s; len=s.size(); for(int i=0;i<len;i++) extend(s[i]-‘a‘); cout<<all()<<endl; return 0; }
以上是关于求不同的子串种类的主要内容,如果未能解决你的问题,请参考以下文章