普通后缀数组的倍增构建
对于单个字符串上的后缀数组的建造,一般都是倍增一个长度
l
,然后对于当前的排序组,每隔
trie上后缀数组的倍增构建
对于一个trie,我们同样可以通过倍增来求,只要把在序列上倍增
k
级变成树上的倍增
似乎在trie上SA建H数组有点不好搞,怎么办呢?没事,我们有波兰表!对于相邻的两个后缀,我们可以用记录下来的
k
级
代码大概是这样:
void build() {
rep (i , 1 , n) rk[i][0] = str[i];
rep (i , 1 , n) pa[i][0] = fa[i];
rep (j , 1 , lg) {
rep (i , 1 , n)
pos[i] = mp(mp(rk[i][j - 1] , rk[pa[i][j - 1]][j - 1]) , i) ,
pa[i][j] = pa[pa[i][j - 1]][j - 1];
sort(pos + 1 , pos + n + 1);
rk[pos[1].sec][j] = 1;
int p = 1;
rep (i , 2 , n)
rk[pos[i].sec][j] = (pos[i - 1].fir == pos[i].fir) ? p : ++ p;
}
}
int LCP(int u , int v) {
if (u == v)
dep[u];
int l = 0;
per (i , lg , 0) if (rk[u][i] == rk[v][i]) {
l += 1 << i;
u = pa[u][i] , v = pa[v][i];
}
return l;
}