终于有算最长重复子串(数)的后缀数组啦,nice

#include <cstdio>
#include <string>
#include <algorithm>
using namespace std;

const int MAX = 25000;

  1#include <cstdio>
  2#include <string>
  3#include <algorithm>
  4using namespace std;
  5
  6const int MAX = 25000;
  7int num[MAX];
  8int mem[3][MAX], c[MAX];
  9int * SA, * Rank, * nSA, * nRank;
 10int n,kk,nmax;
 11
 12void make_sa()
 13{
 14    int i,j;
 15    SA = mem[0]; Rank = mem[1]; nSA = mem[2];
 16    memset(c,0,sizeof(c));
 17    for(i=0;i<n;i++{
 18        c[ num[i] +1++;
 19    }

 20    for(i=1;i<=nmax+1;i++{
 21        c[i] += c[i-1];
 22    }

 23    for(i=0;i<n;i++{
 24        SA[ --c[ num[i] +1] ] = i;
 25    }

 26    Rank[ SA[0] ] = 0;
 27    for(i=1;i<n;i++{
 28        Rank[SA[i]] = Rank[SA[i-1]];
 29        if(num[SA[i]] != num[SA[i-1]]) {
 30            Rank[SA[i]] ++;
 31        }

 32    }

 33
 34    int k;
 35    for(k=1;k<&& Rank[ SA[n-1] ] < n-1;k*=2{
 36        memset(c,0,sizeof(c));
 37        for(i=0;i<n;i++{
 38            c[ Rank[SA[i]] ] ++;
 39        }

 40        for(i=1;i<n;i++{
 41            c[i] += c[i-1];
 42        }

 43        for(i=n-1;i>=0;i--{
 44            if(SA[i] >= k) {
 45                nSA[ -- c[ Rank[SA[i]-k] ] ] = SA[i] - k;
 46            }

 47        }

 48        for(i=n-k;i<n;i++{
 49            nSA[ -- c[Rank[i]] ] = i;
 50        }

 51        nRank = SA;
 52        nRank[ nSA[0] ] = 0;
 53        for(i=1;i<n;i++{
 54            nRank[ nSA[i] ] = nRank[ nSA[i-1] ];
 55            if(Rank[nSA[i]] != Rank[nSA[i-1]] || Rank[nSA[i]+k] != Rank[nSA[i-1]+k]) {
 56                nRank[ nSA[i] ] ++;
 57            }

 58        }

 59        SA = nSA;
 60        nSA = Rank;
 61        Rank = nRank;
 62    }

 63}

 64
 65int h[MAX];
 66int get_lcp()
 67{
 68    int i,j,k;
 69    
 70    for(i=0,k=0;i<n;i++{
 71        if(Rank[i] == n-1{
 72            h[ Rank[i] ] = k = 0;
 73        }

 74        else {
 75            if(k > 0{
 76                k --;
 77            }

 78            j = SA[Rank[i] +1];
 79            while(num[i+k] == num[j+k]) {
 80                k ++;
 81            }

 82            h[ Rank[i] ] = k;
 83        }

 84    }

 85    int ret = 0;
 86    kk --;
 87    for(i=0;i<n-kk;i++{
 88        int t = INT_MAX;
 89        for(j=0;j<kk;j++{
 90            t = min(t, h[i+j]);
 91        }

 92        ret = max(t, ret);
 93    }

 94    return ret;
 95}

 96
 97int main()
 98{
 99    int i,j;
100    while(scanf("%d %d"&n,&kk)==2{
101        nmax = -1;
102        for(i=0;i<n;i++{
103            scanf("%d", num+i);
104            nmax = max(nmax, num[i]);
105        }

106        num[n ++= -1;
107        make_sa();
108        printf("%d\n", get_lcp());
109    }

110}

111


 

posted on 2007-09-30 23:33  xmx  阅读(1353)  评论(1)    收藏  举报

导航