代码
int n, arry[maxn];
int rank[maxn], sa[maxn], _rank[maxn];
bool cmpc(int i, int j){
return arry[i] < arry[j];
}
int ll;
bool cmps(int i, int j){
if (_rank[i] == _rank[j]){
if (i + ll >= n) return true ;
if (j + ll >= n) return false ;
return _rank[i+ll] < _rank[j+ll];
}
else return _rank[i] < _rank[j];
}
void cal_sa(){
for (int i = 0 ; i < n; i++) sa[i] = i; sort(sa, sa+n, cmpc);
rank[sa[0 ]] = 0 ;
for (int i = 1 ; i < n; i++){
if (!cmpc(sa[i-1 ], sa[i]) && !cmpc(sa[i], sa[i-1 ])) rank[sa[i]] = rank[sa[i-1 ]];
else rank[sa[i]] = i;
}
for (int l = 2 , hl = 1 ; hl < n; l *= 2 , hl *= 2 ){
ll = hl;
sort(sa, sa+n, cmps);
for (int i = 0 ; i < n; i++) _rank[i] = rank[i];
rank[sa[0 ]] = 0 ;
for (int i = 1 ; i < n; i++){
if (!cmps(sa[i-1 ], sa[i]) && !cmps(sa[i], sa[i-1 ])) rank[sa[i]] = rank[sa[i-1 ]];
else rank[sa[i]] = i;
}
}
}
int hght[maxn];
void calc_hght(){
int k = 0 ;
for (int i = 0 ; i < n; ++i){
if (rank[i] == 0 ) continue ;
int j = sa[rank[i]-1 ];
if (k > 0 ) --k;
while (arry[i+k] == arry[j+k]) ++k;
hght[rank[i]] = k;
}
}