問題描述
給出一些串,多組詢問求兩個串的最長公共前綴。字符串總長 < 10^6。
輸入格式
第一行一個整數n,表示字符串的個數。
接下來n行,每行一個字符串(字符串不含空格)。
第n+2行一個整數m,表示詢問總數。
接下來m行,每行兩個整數a,b,表示詢問第a個字符串和第b個字符串的最長公共前綴的長度。
輸出格式
輸出共m行,對於每個詢問輸出最長的公共前綴的長度
輸入樣例
5
abcdef
abcd
acd
cade
abcdef
4
1 2
2 3
1 5
3 4
輸出樣例
4
1
6
0
限制與約定
1<= m < 10^6
時間限制:1s
空間限制:256MB
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int maxn = 1000000 + 10 ; int n,ch[maxn][30],val[maxn],cnt,m; int f[maxn][31],Dep[maxn]; string str[30010]; void dfs(int u,int fa) { Dep[u]=Dep[fa]+1; for(int i=0;i<=29;i++) f[u][i+1]=f[f[u][i]][i]; for(int i=0;i<=26;i++) { int v = ch[u][i]; if(!v) continue; f[v][0]=u; dfs(v,u); } } void insert(int pos) { int len = str[pos].length(),u=0; for(int i=0;i<len;i++) { int x = str[pos][i]-'a'; if(!ch[u][x]) ch[u][x]=++cnt; u=ch[u][x]; } val[pos]=u; } int LCA(int x,int y) { if(Dep[x]<Dep[y]) swap(x,y); for(int i=30;i>=0;i--) { if(Dep[f[x][i]]>=Dep[y]) x=f[x][i]; if(x==y) return x; } for(int i=30;i>=0;i--) if(f[x][i]!=f[y][i]) { x=f[x][i]; y=f[y][i]; } return f[x][0]; } int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>str[i]; insert(i); } dfs(0,-1); cin>>m; for(int i=1,a,b;i<=m;i++) { scanf("%d%d",&a,&b); int lca=LCA(val[a],val[b]); printf("%d\n",Dep[lca]-1); } return 0; }