SAM spoj SUBST1 New Distinct Substring
Given a string, we need to find the total number of its distinct substrings.
Input
T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000
Output
For each test case output one number saying the number of distinct substrings.
Example
Input: 2 CCCCC ABABA Output: 5 9
l[] 维护节点长度最大值
l[f[i]]=min[i]-1
在sam上的一个节点i上,有贡献是子串数量就是 max[i]-min[i]+1
因为只维护max,而min可以由f[i]的max+1得到
所以i贡献的答案是=max[i]-min[i]+1=l[i]-l[f[i]]
1 #include<cstring> 2 #include<cstdio> 3 #include<algorithm> 4 #include<map> 5 #include<iostream> 6 using namespace std; 7 const int N=80005; 8 map<int,int>c[N]; 9 int T,n,f[N],l[N],pre,cnt; 10 typedef long long ll; 11 char s[N]; 12 ll ans; 13 inline void clr(){ 14 pre=cnt=1;ans=0; 15 memset(f,0,sizeof(f));memset(l,0,sizeof(l)); 16 for(int i=0;i<N;++i)c[i].clear(); 17 } 18 inline void ins(int x){ 19 int p=pre,np=++cnt;pre=np; 20 l[np]=l[p]+1; 21 for(;p&&!c[p].count(x);p=f[p])c[p][x]=np; 22 if(!p)f[np]=1; 23 else{ 24 int q=c[p][x]; 25 if(l[q]==l[p]+1)f[np]=q; 26 else{ 27 int nq=++cnt; 28 l[nq]=l[p]+1; 29 c[nq]=c[q];f[nq]=f[q]; 30 f[q]=f[np]=nq; 31 for(;c[p][x]==q;p=f[p]) c[p][x]=nq; 32 } 33 } 34 } 35 int main(){ 36 scanf("%d",&T); 37 while(T--){clr(); 38 scanf("%s",s); 39 n=strlen(s); 40 for(int i=0;i<n;++i){ 41 ins(s[i]); 42 } 43 for(int i=1;i<=cnt;++i)ans+=(ll)(l[i]-l[f[i]]); 44 cout<<ans<<endl; 45 } 46 return 0; 47 }