标签:wap oid lca target 题目 lld for typedef ++
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2746
题解:
这个是讲课时候的题。
讲课的时候都在想怎么后缀自动机....
当然是能做啦,$SAM$这么强。
实际上是个$AC$自动机,按照题目模拟就行了。
代码:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 1 << 20 ; const int mod = 1000000007 ; const int P = 21 ; queue <int> Q; int n, m, ch[N][26], fail[N][25], dep[N], tail, cnt, pos[N << 1], lenth[N]; char str[N]; ll Hash[N]; void insert() { int len = strlen(str); int p = 0; for (int i = 0; i < len; i ++ ) { int c = str[i] - ‘a‘; if (!ch[p][c]) { ch[p][c] = ++tail; Hash[ch[p][c]] = (((Hash[p] * 26) % mod) + c) % mod; } pos[ ++ cnt] = ch[p][c]; p = ch[p][c]; } } void getfail() { dep[0] = 0; for (int i = 0; i < 26; i ++ ) { if (ch[0][i]) { fail[ch[0][i]][0] = 0; dep[ch[0][i]] = 1; Q.push(ch[0][i]); } } while (!Q.empty()) { int top = Q.front(); Q.pop(); for (int i = 0; i < 26; i ++ ) { if (!ch[top][i]) { ch[top][i] = ch[fail[top][0]][i]; continue; } int u = ch[top][i]; fail[u][0] = ch[fail[top][0]][i]; dep[u] = dep[fail[u][0]] + 1; for (int j = 1; j < P; j ++ ) { fail[u][j] = fail[fail[u][j - 1]][j - 1]; } Q.push(u); } } } int getlca(int u, int v) { if (dep[u] < dep[v]) { swap(u, v); } int d = dep[u] - dep[v]; for (int i = 0; d; d >>= 1, i ++ ) { if (d & 1) { u = fail[u][i]; } } if (u == v) { return u; } for (int p = P - 1; p >= 0; p -- ) { if (fail[u][p] != fail[v][p]) { u = fail[u][p]; v = fail[v][p]; } } return fail[u][0]; } int main() { scanf("%d", &n); memset(fail, 0, sizeof fail); lenth[0] = 0; for (int i = 1; i <= n; i ++ ) { scanf("%s", str); insert(); lenth[i] = strlen(str); lenth[i] += lenth[i - 1]; } getfail(); scanf("%d", &m); while (m -- ) { int p1, l1, p2, l2; scanf("%d%d%d%d", &p1, &l1, &p2, &l2); int t1 = pos[lenth[p1 - 1] + l1]; int t2 = pos[lenth[p2 - 1] + l2]; int lca = getlca(t1, t2); printf("%lld\n", Hash[lca]); } return 0; }
小结:注意一下AC自动机找LCA要倍增,别直接跳fail......
[bzoj2746][HEOI2012]旅行问题 _AC自动机_倍增
标签:wap oid lca target 题目 lld for typedef ++
原文地址:https://www.cnblogs.com/ShuraK/p/11421154.html