wls的数据结构-字典树
存储方式
字符集太大了,可以采用hash开字典树
log时间查询任意两个字符串的最大前缀
建字典树,然后查询lca
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 5e5+10;
struct Node{
int son[26];
int depth;
}tr[N];
int f[N][20];
int tot, root;
int whed[N];
char s[10010];
void insert(int id, char s[]){
int p = root;
for(int i = 1; s[i]; i ++){
int t = s[i] - 'a';
if(!tr[p].son[t]){
tr[p].son[t] = ++tot;
tr[tot].depth = tr[p].depth + 1;
f[tot][0] = p;
}
p = tr[p].son[t];
}
whed[id] = p;
}
int main(){
int n; scanf("%d", &n);
root = ++ tot;
for(int i = 1; i <= n; i ++){
scanf("%s", s + 1);
insert(i, s);
}
// for(int i = 1; i <= tot; i ++) cout << f[i][0] << ' ';
// cout << endl;
for(int i = 1; i < 20; i ++){
for(int j = 1; j <= tot; j ++){
if(f[j][i - 1]) f[j][i] = f[f[j][i - 1]][i - 1];
}
}
// cout << f[5][0] << "__" << endl;
int q; scanf("%d", &q);
while(q--){
int x, y; scanf("%d %d", &x, &y);
x = whed[x], y = whed[y];
// cout << x << ' ' << y << endl;
if(tr[x].depth < tr[y].depth) swap(x, y);
int z = tr[x].depth - tr[y].depth;
// cout << z << endl;
for(int j = 20; j >= 0; j --){
if(z >> j & 1) x = f[x][j];
}
// cout << x << ' ' << y << endl;8
if(x == y){
printf("%d\n", tr[x].depth);
continue;
}
for(int j = 19; j >= 0; j --){
// cout << x << ' ' << y << ' ' << f[x][j] << ' ' << f[y][j] << ' ' << "zz" << endl;
if(f[x][j] != f[y][j]) x = f[x][j], y = f[y][j];
}
// cout << x << ' ' << y << ' ' << "zz" << endl;
printf("%d\n", tr[f[x][0]].depth);
}
return 0;
}