1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| #include <cstdio> #include <iostream> #include <string> #include <algorithm> #include <cmath> #include <cstring> using namespace std; #define MAXN 1011 int n,k;
int Rank[MAXN]; int tmp[MAXN]; char s[MAXN]; int lcp[MAXN],sa[MAXN];
bool cmpSa(int i, int j) { if(Rank[i] != Rank[j])return Rank[i] < Rank[j]; else {
int ri = i+k <=n? Rank[i+k]:-1; int rj = j+k <= n ? Rank[j+k]:-1; return ri <rj; } }
void consa() {
for(int i=0;i<=n;i++){ sa[i]=i;Rank[i] = i < n?s[i]:-1; } for(k=1;k<=n;k*=2) { sort(sa,sa+n+1,cmpSa); tmp[sa[0]] = 0; for(int i=1;i<=n;i++){ tmp[sa[i]] = tmp[sa[i-1]] +(cmpSa(sa[i-1],sa[i])?1:0);
} for(int i=0;i<=n;i++){ Rank[i] = tmp[i]; } } } void construct_lcp() { for(int i=0; i<=n; i++)Rank[sa[i]]=i; int h=0; lcp[0]=0; for(int i=0;i<n;i++) { int j=sa[Rank[i]-1]; if(h>0)h--; for(; j+h<n && i+h<n; h++) { if(s[j+h]!=s[i+h])break; } lcp[Rank[i]-1]=h; } } int main() { int t,ans; scanf("%d",&t); while(t--) { ans=0; scanf("%s",s); n=strlen(s); consa(); construct_lcp(); for(int i=1;i<=n;i++) { ans+=n-sa[i]-lcp[i-1]; } printf("%d\n",ans); } return 0; return 0; }
|