POJ3261Milk Patterns后缀数组

第一道后缀数组的题目,求得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 }
原文地址:https://www.cnblogs.com/caozhenhai/p/2969218.html