贴一波计算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 ;
}
}