倒数第二个点MLE,其他全部卡过去了。
#include<bits/stdc++.h>
#define MAXN 1000001
#define MOD 1000000007
using namespace std;
typedef long long ll;
int n, m, cnt;
char c[MAXN];
vector<int> pos[MAXN], e[MAXN];
vector<int> dep, fa[20];
struct ACAM{
int sz;
int fail[MAXN], trie[MAXN][26];
vector<int> val;
void insert(char *s, int id){
int now = 0, l = strlen(s);
for(int i = 0; i < l; i++){
int to = s[i] - 'a';
if(!trie[now][to]){
trie[now][to] = ++sz;
val.push_back(((ll)val[now] * 26 + to) % MOD);
dep.push_back(0);
for(int i = 0; i < 20; i++) fa[i].push_back(0);
}
pos[id].push_back(trie[now][to]);
now = trie[now][to];
}
}
void build(){
queue<int> q;
for(int i = 0; i < 26; i++) if(trie[0][i]) q.push(trie[0][i]);
while(!q.empty()){
int now = q.front(); q.pop();
e[fail[now]].push_back(now);
for(int i = 0; i < 26; i++){
if(!trie[now][i]) trie[now][i] = trie[fail[now]][i];
else{
fail[trie[now][i]] = trie[fail[now]][i];
q.push(trie[now][i]);
}
}
}
}
}AC;
void lca_init(){
queue<int> q; q.push(0); dep[0] = 1;
while(!q.empty()){
int now = q.front(); q.pop();
int siz = e[now].size();
for(int i = 0; i < siz; i++){
int to = e[now][i];
if(dep[to]) continue;
dep[to] = dep[now] + 1;
fa[0][to] = now;
q.push(to);
}
}
for(int i = 1; i < 20; i++){
for(int j = 1; j <= AC.sz; j++){
fa[i][j] = fa[i - 1][fa[i - 1][j]];
}
}
}
int get_lca(int u, int v){
if(dep[u] > dep[v]) swap(u, v);
for(int i = 19; i >= 0; i--){
if(dep[v] - (1 << i) >= dep[u]) v = fa[i][v];
}
if(u == v) return u;
for(int i = 19; i >= 0; i--){
if(fa[i][u] != fa[i][v]){
u = fa[i][u];
v = fa[i][v];
}
}
return fa[0][v];
}
void init(){
AC.val.push_back(0);
dep.push_back(0);
for(int i = 0; i < 20; i++) fa[i].push_back(0);
}
int main(){
init();
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%s", c);
AC.insert(c, i);
}
AC.build();
lca_init();
scanf("%d",&m);
while(m--){
int i, j, k, l;
scanf("%d%d%d%d",&i,&j,&k,&l);
int lca = get_lca(pos[i][j - 1], pos[k][l - 1]);
printf("%d\n",AC.val[lca]);
}
return 0;
}