第一道后缀数组的题目,求得height之后,二分答案就可以,后缀数组的数组绕来绕去,实在感觉有点乱七八糟啊,整体复杂度为nlogn,包过
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 #define N 20005 6 #define M 100005 7 #define max(a,b) ((a)>(b)?(a):(b)) 8 int s[N]; 9 int sa[N],rank[N],height[N]; 10 int t[N],t2[N],c[M],n,ti; 11 void build_sa(int m) 12 { 13 int i,k,*x = t, *y = t2; 14 memset(c,0,sizeof(c)); 15 for(i = 0;i < n; i++) 16 { 17 c[x[i] = s[i]]++; 18 } 19 for(i = 1;i < m; i++) 20 { 21 c[i] += c[i-1]; 22 } 23 for(i = n - 1; i >= 0; i--) 24 sa[--c[x[i]]] = i; 25 for(k = 1; k <= n ; k <<= 1) 26 { 27 int p = 0; 28 for(i = n - k; i < n; i++) 29 y[p++] = i; 30 for(i = 0; i < n; i++) 31 if(sa[i] >= k) 32 y[p++] = sa[i] - k; 33 memset(c,0,sizeof(c)); 34 for(i = 0; i < n; i++) 35 c[x[y[i]]]++; 36 for(i = 1; i < m; i++) 37 c[i] += c[i-1]; 38 for(i = n - 1; i >= 0; i--) 39 sa[--c[x[y[i]]]] = y[i]; 40 swap(x,y); 41 p = 1; 42 x[sa[0]] = 0; 43 for(i = 1; i < n; i++) 44 x[sa[i]] = ((y[sa[i - 1]] == y[sa[i]]) && (y[sa[i - 1] + k] == y[sa[i] + k]))?p - 1:p++; 45 if(p >= n) 46 break; 47 m = p; 48 } 49 } 50 void geth() 51 { 52 int i,j,k = 0; 53 for(i = 0; i < n; i++) 54 rank[sa[i]] = i; 55 for(i = 0; i < n; i++) 56 { 57 if(k) 58 k--; 59 j = sa[rank[i] - 1]; 60 while(s[i+k] == s[j+k]) 61 k++; 62 height[rank[i]] = k; 63 } 64 } 65 bool check(int len) 66 { 67 int i; 68 int sum; 69 sum = 0; 70 for(i = 0; i < n; i++) 71 { 72 if(height[i] >= len) 73 { 74 sum++; 75 if(sum == ti - 1) 76 return true; 77 } 78 else 79 { 80 sum = 0; 81 } 82 } 83 return false; 84 } 85 int main() 86 { 87 int i,j; 88 int m; 89 int l,r,mid; 90 while(scanf("%d%d",&n,&ti) != EOF) 91 { 92 m = 0; 93 for(i = 0; i < n; i++) 94 { 95 scanf("%d",&s[i]); 96 m = max(m,s[i]); 97 } 98 m++; 99 build_sa(m); 100 geth(); 101 l = 0; 102 r = n; 103 while(l <= r) 104 { 105 mid = (l + r) >>1; 106 if(check(mid)) 107 l = mid + 1; 108 else 109 r = mid - 1; 110 } 111 printf("%d\n",r); 112 } 113 return 0; 114 }