后缀数组(suffix array) 模板(1)

贴一波计算sa数组的模板

void get_sa() {
    int *x = s1, *y = s2 ;
    int i, j, k, p = 1 ;
    memset ( c, 0, sizeof(c) ) ; // 清空桶
    for ( i = 1 ; i <= n ; i ++ ) c[x[i] = s[i]] ++ ; // 入桶
    for ( i = 1 ; i <= m ; i ++ ) c[i] += c[i-1] ; // 从个数到排名
    for ( i = n ; i ; i -- ) sa[ c[x[i]]-- ] = i ; // 从后往前方便统计

    for ( k = 1 ; k <= n ; k <<= 1 ) { // 倍增长度
        p = 0 ;
        //先排第二关键字
        for ( i = n-k+1 ; i <= n ; i ++ ) y[++p] = i ; // 无第二关键字入桶
        for ( i = 1 ; i <= n ; i ++ ) 
            if ( sa[i] > k ) y[++p] = sa[i]-k ; // 入桶
        //再排第一关键字
        memset ( c, 0, sizeof(c) ) ;
        for ( i = 1 ; i <= n ; i ++ ) c[ x[y[i]] ] ++ ;
        for ( i = 1 ; i <= m ; i ++ ) c[i] += c[i-1] ;
        for ( i = n ; i ; i -- ) sa[ c[x[y[i]]]-- ] = y[i] ; // 注意是y[i]
        swap(x, y) ;
        p = 1 ;
        x[sa[1]] = 1 ;
        for ( i = 2 ; i <= n ; i ++ )
            x[sa[i]] = y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k] ? p : ++p ; // 相同则是相同的排名
        if ( p >= n ) break ;
        m = p ;
    }
}
点赞