为啥SA在每次build还要把rk数组清空/yiw
void build(char *s) {
int m = 1 << 7, p = 0;
memset(buc, 0, sizeof buc);
memset(rk, 0, sizeof rk);
for(int i = 1; i <= n; ++ i) buc[rk[i] = s[i]] ++;
for(int i = 1; i <= m; ++ i) buc[i] += buc[i - 1];
for(int i = n; i; -- i) sa[buc[rk[i]] -- ] = i;
for(int w = 1; ; m = p, p = 0, w <<= 1) {
for(int i = n - w + 1; i <= n; ++ i) id[ ++ p] = i;
for(int i = 1; i <= n; ++ i) if(sa[i] > w) id[ ++ p] = sa[i] - w;
p = 0;
memset(buc, 0, sizeof buc);
memcpy(ork, rk, sizeof rk);
for(int i = 1; i <= n; ++ i) buc[rk[i]] ++;
for(int i = 1; i <= m; ++ i) buc[i] += buc[i - 1];
for(int i = n; i; -- i) sa[buc[rk[id[i]]] -- ] = id[i];
for(int i = 1; i <= n; ++ i) rk[sa[i]] = same(sa[i], sa[i - 1], w) ? p : ++ p;
if(p == n) break;
}
for(int i = 1, k = 0; i <= n; ++ i) {
if(k) k --;
while(s[i + k] == s[sa[rk[i] - 1] + k]) k ++;
ht[rk[i]] = st[rk[i]][0] = k;
}
for(int j = 1; j <= lg[n]; ++ j) {
for(int i = 1; i + (1 << j) - 1 <= n; ++ i) {
st[i][j] = min(st[i][j - 1], st[i + (1 << j - 1)][j - 1]);
}
}
}