[CF452E]Three strings

题目大意:给你三个字符串$A,B,C$,令$L=min(|A|,|B|,|C|)$,对每个$iin[1,L]$,求出符合$A_{[a,a+i)}=B_{[b,b+i)}=C_{[c,c+i)}$的三元组$(a,b,c)$的个数

题解:先建一棵广义$SAM$,求出每个点可以到达的$A,B,C$的字串的个数,然后这个点贡献的值就是三个串分别的个数乘起来,发现一个点会对$[R_{fail_p+1},R_{p}]$的区间产生贡献,可以差分一下维护。

卡点:

C++ Code:

#include <algorithm>
#include <cstdio>
#include <cstring>
#define maxn 300010
const int mod = 1e9 + 7;
inline void reduce(int &x) {x += x >> 31 & mod;}

int n = 0x3f3f3f3f;
int ans[maxn];
namespace SAM {
#define N (maxn * 3 << 1)
	int R[N], fail[N], nxt[N][26];
	int lst = 1, idx = 1, sz[N][3];

	void append(int ch, int tg) {
		int p = lst, np = lst = ++idx; R[np] = R[p] + 1, sz[np][tg] = 1;
		for (; p && !nxt[p][ch]; p = fail[p]) nxt[p][ch] = np;
		if (!p) fail[np] = 1;
		else {
			int q = nxt[p][ch];
			if (R[p] + 1 == R[q]) fail[np] = q;
			else {
				int nq = ++idx;
				fail[nq] = fail[q], R[nq] = R[p] + 1, fail[q] = fail[np] = nq;
				std::copy(nxt[q], nxt[q] + 26, nxt[nq]);
				for (; p && nxt[p][ch] == q; p = fail[p]) nxt[p][ch] = nq;
			}
		}
	}

	int head[N], cnt;
	struct Edge {
		int to, nxt;
	} e[N];
	inline void addedge(int a, int b) {
		e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
	}

	void dfs(int u) {
		for (int i = head[u]; i; i = e[i].nxt) {
			int v = e[i].to;
			dfs(v);
			sz[u][0] += sz[v][0], sz[u][1] += sz[v][1], sz[u][2] += sz[v][2];
		}
	}
	void work() {
		for (int i = 2; i <= idx; i++) addedge(fail[i], i);
		dfs(1);
		for (int i = 2; i <= idx; i++) {
			int tmp = static_cast<long long> (sz[i][0]) * sz[i][1] % mod * sz[i][2] % mod;
			reduce(ans[R[fail[i]] + 1] += tmp - mod), reduce(ans[R[i] + 1] -= tmp);
		}
		for (int i = 2; i <= n; i++) reduce(ans[i] += ans[i - 1] - mod);
	}
#undef N
}

char s[maxn];
int main() {
	for (int i = 0; i < 3; i++) {
		scanf("%s", s); SAM::lst = 1;
		n = std::min(n, static_cast<int> (strlen(s)));
		for (char *ch = s; *ch; ++ch) SAM::append(*ch - 'a', i);
	}
	SAM::work();
	for (int i = 1; i <= n; i++) {
		printf("%d", ans[i]);
		putchar(i == n ? '
' : ' ');
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/Memory-of-winter/p/10164330.html