Questions surface:
Suffix array (SA) is an important data structure, usually doubled or DC3 algorithm, which is beyond the scope of our discussion.
In this problem, we want to use fast row, Hash realized with a simple binary O ( n- L O G 2 n- ) O (Nlog2N) Seeking suffix array.
Specifically, given a string of length n S (subscript 0 ~ n-1), we can use the integer K ( 0 ≤ K < n suffixes S (k string S of 0≤k <n) ~ n-1).
All in accordance with the suffix string S lexicographic order, ranked suffix i is referred to SA [i].
Additionally, we consider the ranking of the ranking suffix i-1 i is a suffix, the length of the longest common prefix both referred to as Height [i].
Our task is to find two arrays SA and Height.
Input Format
Enter a string which length does not exceed 300,000.
Output Format
The first line array SA, the adjacent two integers separated by a space.
The second line array Height, adjacent two integers separated by a space, we require Height [1] = 0.
Sample input:
ponoiiipoi
Sample output:
9 4 5 6 2 8 3 1 7 0 0 1 2 1 0 0 2 1 0 2
Solution:
two stars two of the longest prefix suffix beginning, then depending on the sort function to sort of write,
#include<iostream> #include<algorithm> #include<cstring> #define ull unsigned long long using namespace std; const ull base=131; const ull INT_MIN=-1e6; ull h[300010],p[300010]; int sa[300010];int n; char str[300010]; ull get(int l,int r) { return h[r]-h[l-1]*p[r-l+1]; } int get_max(int a,int b) { int l=0;int r=min(n-a+1,n-b+1); while(l<r) { int mid=(r + l+ 1) >> 1; if(get(a,a+mid-1)!=get(b,b+mid-1))r=mid-1; else l=mid; } return l; } BOOL CMP ( int A, int B) // sort function { int L = get_max (A, B); int AV = A + L> n-INT_MIN:? STR [A + L]; int BV = B + L> n-? INT_MIN: STR [B + L]; return AV < BV; // ascending order; } int main () { Scanf ( " % S " , STR + . 1 ); n- = strlen (STR + . 1 ); P [ 0 ] = . 1 ; for ( int I = . 1 ; I <= n-; I ++ ) { h[i]=h[i-1]*base+str[i]-'a'+1; p[i]=p[i-1]*base; sa[i]=i; } sort(sa+1,sa+n+1,cmp); for(int i=1;i<=n;i++)printf("%d ",sa[i]-1); puts(""); for(int i=1;i<=n;i++) { if(i==1)printf("0 "); else printf("%d ",get_max(sa[i],sa[i-1])); } puts(""); return 0; }