Code:
#include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; const int maxn=1000007; const ll mod=1000000007; queue<int>q; vector<int>get[maxn]; ll id[maxn]; char str[maxn]; int edges,tot; int ch[maxn][30],f[maxn],hd[maxn],to[maxn],nex[maxn],dep[maxn],top[maxn],son[maxn],siz[maxn],fa[maxn]; inline void addedge(int u,int v){ nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } inline void insert(int idx,char ss[]) { int x=0,len=strlen(ss+1),i; for(i=1;i<=len;++i) { int c=ss[i]-'a'; if(!ch[x][c]) { ch[x][c]=++tot,id[ch[x][c]]=(1ll*26*id[x]+c)%mod; } x=ch[x][c]; get[idx].push_back(x); } } inline void getfail() { int i,j; for(i=0;i<27;++i) if(ch[0][i]) addedge(0,ch[0][i]),q.push(ch[0][i]); while(!q.empty()) { int u=q.front();q.pop(); for(i=0;i<27;++i) { int p=ch[u][i]; if(!p) { ch[u][i]=ch[f[u]][i]; continue; } f[p]=ch[f[u]][i], addedge(f[p],p); q.push(p); } } } void dfs1(int u,int ff) { int i; fa[u]=ff,siz[u]=1; for(i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==ff) continue; dep[v]=dep[u]+1,dfs1(v,u), siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; } } void dfs2(int u,int tp) { int i; top[u]=tp; if(son[u]) dfs2(son[u],tp); for(i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==fa[u]||v==son[u]) continue; dfs2(v,v); } } int LCA(int x,int y) { while(top[x]^top[y]) { dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]]; // printf("%d %d ",x,y); } return dep[x]<dep[y]?x:y; } int main() { // setIO("input"); int n,i,j,m; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%s",str+1),insert(i,str); getfail(),dfs1(0,-1),dfs2(0,0); scanf("%d",&m); for(i=1;i<=m;++i) { int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); printf("%lld ",id[LCA(get[a][b-1], get[c][d-1])]); } return 0; }