Advertisement
Matrix_code

strings - Suffix Array O(nlog n)

May 3rd, 2016 (edited)
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.69 KB | None | 0 0
  1. /***************************** END OF TEMPLATE *******************************/
  2. /***************************************************************************************
  3.  *     Suffix Array Implementation O(nlog n)
  4.  *     Definition : suffix(i) => substring [i,n-1]
  5.  *     Input : STRING (inpStr) , sigma => Character Set Size
  6.  Output:
  7.  sa => ith smallest suffix of the string
  8.  rak => rak[i] indicates the position of suffix(i) in the suffix array
  9.  height => height[i] indicates the LCP of i-1 and i th suffix
  10.  *     LCP of suffix(i) & suffix(j) = { L = rak[i], R = rak[j] ,  min(height[L+1, R]);}
  11.  ***************************************************************************************/
  12. #include<bits/stdc++.h>
  13. using namespace std;
  14.  
  15.  
  16. const int maxn = 5e5+5;
  17. int wa[maxn],wb[maxn],wv[maxn],wc[maxn];
  18. int r[maxn],sa[maxn],rak[maxn], height[maxn],dp[maxn][22],jump[maxn], SIGMA = 0 ;
  19.  
  20. int cmp(int *r,int a,int b,int l){return r[a] == r[b] && r[a+l] == r[b+l];}
  21. void da(int *r,int *sa,int n,int m)
  22. {
  23.     int i,j,p,*x=wa,*y=wb,*t;
  24.     for( i=0;i<m;i++) wc[i]=0;
  25.     for( i=0;i<n;i++) wc[x[i]=r[i]] ++;
  26.     for( i=1;i<m;i++) wc[i] += wc[i-1];
  27.     for( i= n-1;i>=0;i--)sa[--wc[x[i]]] = i;
  28.     for( j= 1,p=1;p<n;j*=2,m=p){
  29.         for(p=0,i=n-j;i<n;i++)y[p++] = i;
  30.         for(i=0;i<n;i++)if(sa[i] >= j) y[p++] = sa[i] - j;
  31.         for(i=0;i<n;i++)wv[i] = x[y[i]];
  32.         for(i=0;i<m;i++) wc[i] = 0;
  33.         for(i=0;i<n;i++) wc[wv[i]] ++;
  34.         for(i=1;i<m;i++) wc[i] += wc[i-1];
  35.         for(i=n-1;i>=0;i--) sa[--wc[wv[i]]] = y[i];
  36.         for(t=x,x=y,y=t,p=1,x[sa[0]] = 0,i=1;i<n;i++) x[sa[i]]= cmp(y,sa[i-1],sa[i],j) ? p-1:p++;
  37.     }
  38. }
  39. void calheight(int *r,int *sa,int n)
  40. {
  41.     int i,j,k=0;
  42.     for(i=1;i<=n;i++) rak[sa[i]] = i;
  43.     for(i=0;i<n;height[rak[i++]] = k ) {
  44.         for(k?k--:0, j=sa[rak[i]-1] ; r[i+k] == r[j+k] ; k ++) ;
  45.     }
  46. }
  47.  
  48. void initRMQ(int n)
  49. {
  50.     for(int i= 0;i<=n;i++) dp[i][0] = height[i];
  51.     for(int j= 1; (1<<j) <= n; j ++ ){
  52.         for(int i = 0; i + (1<<j) - 1 <= n ; i ++ ) {
  53.             dp[i][j] = min(dp[i][j-1] , dp[i + (1<<(j-1))][j-1]);
  54.         }
  55.     }
  56.     for(int i = 1;i <= n;i ++ ) {
  57.         int k = 0;
  58.         while((1 << (k+1)) <= i) k++;
  59.         jump[i] = k;
  60.     }
  61.  
  62. }
  63. int askRMQ(int L,int R)
  64. {
  65.     int k = jump[R-L+1];
  66.     return min(dp[L][k], dp[R - (1<<k) + 1][k]);
  67. }
  68.  
  69.  
  70. int main()
  71. {
  72.     scanf("%s",s);
  73.     int n = strlen(s);
  74.     for(int i = 0; i < n; i ++) {
  75.         r[i] = s[i]-'a' + 1;
  76.         SIGMA = max(SIGMA, r[i]);
  77.     }
  78.     r[n] = 0;
  79.     da(r,sa,n+1,SIGMA + 1); // don't forget SIGMA + 1. It will ruin you.
  80.     calheight(r,sa,n);
  81. }
  82.  
  83.  
  84. /*==============================================================================*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement