枚举子串的长度,然后判断是不是最远位置和最近的相隔满足大于等于子串的长度就好,,(然而本蒟蒻还是不会)
1 #include<bits/stdc++.h> 2 #define N 100005<<2 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 int n,k,p,q,ans; 14 int a[1005],v[1005]; 15 int sa[2][1005],rk[2][1005],h[1005]; 16 char ch[1005]; 17 void cal_sa(int sa[N], int rk[N], int Sa[N], int Rk[N]) 18 { 19 for (int i=1; i<=n; i++) v[rk[sa[i]]]=i; 20 for (int i=n; i>=1; i--) 21 if (sa[i]>k) Sa[v[rk[sa[i]-k]]--]=sa[i]-k; 22 for (int i=n-k+1; i<=n; i++) 23 Sa[v[rk[i]]--]=i; 24 for (int i=1; i<=n; i++) Rk[Sa[i]]=Rk[Sa[i-1]]+(rk[Sa[i]]!=rk[Sa[i-1]] || rk[Sa[i]+k]!=rk[Sa[i-1]+k]); 25 } 26 void work() 27 { 28 p=0,q=1; 29 for (int i=1; i<=n; i++) v[a[i]]++; 30 for (int i=1; i<=30; i++) v[i]+=v[i-1]; 31 for (int i=1; i<=n; i++) sa[p][v[a[i]]--]=i; 32 for (int i=1; i<=n; i++) rk[p][sa[p][i]]=rk[p][sa[p][i-1]]+(a[sa[p][i]]!=a[sa[p][i-1]]); 33 for (k=1; k<n; k<<=1,q^=1,p^=1) cal_sa(sa[p],rk[p],sa[q],rk[q]); 34 } 35 void get_height() 36 { 37 k=0; 38 for (int i=1; i<=n; i++) 39 { 40 if (rk[p][i]==1) h[1]=0; 41 else{ 42 int j=sa[p][rk[p][i]-1]; 43 while (a[i+k]==a[j+k]) k++; 44 h[rk[p][i]]=k; 45 if (k>0) k--; 46 } 47 } 48 } 49 bool solve(int x) 50 { 51 bool flag=0; 52 int mx=sa[p][1],mn=sa[p][1]; 53 for (int i=2; i<=n; i++) 54 if (h[i]<x) 55 { 56 if (mx-mn>=x) ans++,flag=1; 57 mx=mn=sa[p][i]; 58 } 59 else 60 { 61 mx=max(mx,sa[p][i]); 62 mn=min(mn,sa[p][i]); 63 } 64 if (mx-mn>=x) ans++,flag=1; 65 return flag; 66 } 67 int main() 68 { 69 while (scanf("%s",ch+1)) 70 { 71 if (ch[1]=='#') break; 72 memset(a,0,sizeof(a)); 73 memset(v,0,sizeof(v)); 74 memset(rk,0,sizeof(rk)); 75 memset(sa,0,sizeof(sa)); 76 n=strlen(ch+1); 77 for (int i=1; i<=n; i++) a[i]=ch[i]-'a'+1; 78 work(); get_height(); 79 ans=0; 80 for (int i=1; i<=(n+1)/2; i++) 81 if (!solve(i)) break; 82 cout<<ans<<endl; 83 } 84 return 0; 85 }