裸的统计不同的重复出现子串(不重叠)种数的题。
多次使用后缀排序要注意小细节。y数组在重复使用时一定要清空,看那个line25 +k就明白了 ,cnt也要清空,为什么就不说了
1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
5 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
6 const int N=1000+7;
7 char s[N];
8 int n,m;
9 ll ans;
10
11 int sa[N],rk[N],x[N],y[N],cnt[N],h[N],p;
12 inline void build(){
13 memset(cnt,0,sizeof cnt);memset(y,0,sizeof y);//
14 for(register int i=1;i<=n;++i)++cnt[x[i]=s[i]];
15 for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1];
16 for(register int i=n;i;--i)sa[cnt[x[i]]--]=i;
17 for(register int k=1;k<n;k<<=1,p=0){
18 for(register int i=n-k+1;i<=n;++i)y[++p]=i;
19 for(register int i=1;i<=n;++i)if(sa[i]>k)y[++p]=sa[i]-k;
20 for(register int i=1;i<=m;++i)cnt[i]=0;
21 for(register int i=1;i<=n;++i)++cnt[x[y[i]]];
22 for(register int i=1;i<=m;++i)cnt[i]+=cnt[i-1];
23 for(register int i=n;i;--i)sa[cnt[x[y[i]]]--]=y[i];
24 swap(x,y);x[sa[1]]=p=1;
25 for(register int i=2;i<=n;++i)x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p:++p;
26 if(p==n)break; m=p;
27 }p=0;
28 // for(register int i=1;i<=n;++i)printf("%d %d
",i,x[i]);
29 for(register int i=1;i<=n;h[x[i]]=p,p?--p:1,++i)while(s[i+p]==s[sa[x[i]-1]+p]&&++p);
30 }
31
32 inline void search(int k){
33 int l=sa[1],r=sa[1];
34 for(register int i=2;i<=n;++i){
35 if(h[i]<k){r-l>=k?++ans:1;l=r=sa[i];}
36 MIN(l,sa[i]),MAX(r,sa[i]);
37 }
38 r-l>=k?++ans:1;
39 }
40
41 int main(){
42 while(~scanf("%s",s+1)){
43 if(s[1]=='#')break;
44 n=strlen(s+1),m=127,ans=0,p=0,build();
45 for(register int i=1;i<=n/2;++i)search(i);
46 printf("%lld
",ans);
47 }
48 return 0;
49 }