標籤:swa while space scan sub char color res pre
https://vjudge.net/problem/SPOJ-DISUBSTR
有兩種方式來求去除重讀的子串
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn = 50005; 5 6 int t1[maxn],t2[maxn],c[maxn]; 7 bool cmp(int *r,int a,int b,int l) { 8 return r[a]==r[b] &&r[l+a] == r[l+b]; 9 }10 11 void get_sa(int str[],int sa[],int Rank[],int height[],int n,int m)12 {13 n++;14 int p,*x=t1,*y=t2;15 for(int i = 0; i < m; i++) c[i] = 0;16 for(int i = 0; i < n; i++) c[x[i] = str[i]]++;17 for(int i = 1; i < m; i++) c[i] += c[i-1];18 for(int i = n-1; i>=0; i--) sa[--c[x[i]]] = i;19 for(int j = 1; j <= n; j <<= 1) {20 p = 0;21 for(int i = n-j; i < n; i++) y[p++] = i;22 for(int i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i]-j;23 for(int i = 0; i < m; i++) c[i] = 0;24 for(int i = 0; i < n; i++) c[x[y[i]]]++ ;25 for(int i = 1; i < m; i++) c[i] += c[i-1];26 for(int i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i];27 swap(x,y);28 p = 1;29 x[sa[0]] = 0;30 for(int i = 1; i < n; i++)31 x[sa[i]] = cmp(y,sa[i-1],sa[i],j)? p-1:p++;32 if(p >= n) break;33 m = p;34 }35 int k = 0;36 n--;37 for(int i = 0; i <= n; i++)38 Rank[sa[i]] = i;39 for(int i = 0; i < n; i++) {40 if(k) k--;41 int j = sa[Rank[i]-1];42 while(str[i+k] == str[j+k]) k++;43 height[Rank[i]] = k;44 }45 }46 47 int Rank[maxn],height[maxn];48 int sa[maxn];49 char str[maxn];50 int a[maxn];51 int n;52 53 int main()54 {55 int T;56 scanf("%d",&T);57 while(T--)58 {59 int tot = 0;60 scanf("%s",str);61 int len = strlen(str);62 for(int i = 0;i < len; i++)63 a[i] = str[i];64 a[len] = 0;65 get_sa(a,sa,Rank,height,len,200);66 long long res = 0;67 long long ans = (len+1)*len/2;68 for(int i=1;i<=len;i++){69 res+=len-sa[i]-height[i];70 ans-=height[i];71 }72 //printf("%lld\n",res);73 printf("%lld\n", ans);74 }75 return 0;76 }
C - Distinct Substrings (模板)