acwing 140. suffix array

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;
}

 

Guess you like

Origin www.cnblogs.com/flyljz/p/11649133.html