标签: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 }
标签:swa while space scan sub char color res pre
原文地址:https://www.cnblogs.com/ouyang_wsgwz/p/9757396.html