题目
Luogu
LOJ
Acwing
思路
代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 400010;
int last = 1, tot = 1;
int n, m, b[N], pos[N], sz[N];
long long f[N], res;
string A, B;
struct NODE { int len, link, ch[26]; } node[N];
void insert(int c) {
int p = last, np = last = ++tot;
node[np].len = node[p].len + 1, sz[np] = 1;
for (; p && !node[p].ch[c]; p = node[p].link) node[p].ch[c] = np;
if (!p) return node[np].link = 1, void(0);
int q = node[p].ch[c];
if (node[q].len == node[p].len + 1) return node[np].link = q, void(0);
int nq = ++tot;
node[nq] = node[q], node[nq].len = node[p].len + 1;
node[np].link = node[q].link = nq;
for (; p && node[p].ch[c] == q; p = node[p].link) node[p].ch[c] = nq;
}
void topsort() {
for (int i = 1; i <= tot; i++) b[node[i].len]++;
for (int i = 1; i <= tot; i++) b[i] += b[i - 1];
for (int i = 1; i <= tot; i++) pos[b[node[i].len]--] = i;
for (int i = tot; i >= 1; i--) sz[node[pos[i]].link] += sz[pos[i]];
for (int i = 2; i <= tot; i++)
f[pos[i]] = 1ll * (node[pos[i]].len - node[node[pos[i]].link].len) *
sz[pos[i]] + f[node[pos[i]].link];
}
void match() {
for (int i = 0, j = 1, k = 0; i < B.size(); i++) {
int c = B[i] - 'a';
while (j && !node[j].ch[c]) j = node[j].link;
if (!j) { j = 1, k = 0; continue; }
k = min(k, node[j].len) + 1, j = node[j].ch[c];
res += f[node[j].link] + 1ll * (k - node[node[j].link].len) * sz[j];
}
}
signed main() {
cin >> A >> B;
for (int i = 0; i < A.size(); i++) insert(A[i] - 'a');
topsort(), match();
cout << res << endl;
return 0;
}