AC自动机 + 倍增 LCA MLE 求助
查看原帖
AC自动机 + 倍增 LCA MLE 求助
547908
NightTide楼主2024/11/2 15:13

倒数第二个点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;
}
2024/11/2 15:13
加载中...