题目大意:给你三个字符串$A,B,C$,令$L=min(|A|,|B|,|C|)$,对每个$i\in[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 ? '\n' : ' ');
}
return 0;
}

  

[CF452E]Three strings的更多相关文章

  1. CF452E Three strings 广义后缀自动机

    建一个广义后缀自动机统计一下就行,好长时间不敲后缀自动机调了半天~ #include <bits/stdc++.h> using namespace std; namespace IO { ...

  2. Hacker Rank: Two Strings - thinking in C# 15+ ways

    March 18, 2016 Problem statement: https://www.hackerrank.com/challenges/two-strings/submissions/code ...

  3. StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing the strings?

    StackOverFlow排错翻译 - Python字符串替换: How do I replace everything between two strings without replacing t ...

  4. Multiply Strings

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  5. [LeetCode] Add Strings 字符串相加

    Given two non-negative numbers num1 and num2 represented as string, return the sum of num1 and num2. ...

  6. [LeetCode] Encode and Decode Strings 加码解码字符串

    Design an algorithm to encode a list of strings to a string. The encoded string is then sent over th ...

  7. [LeetCode] Group Shifted Strings 群组偏移字符串

    Given a string, we can "shift" each of its letter to its successive letter, for example: & ...

  8. [LeetCode] Isomorphic Strings 同构字符串

    Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...

  9. [LeetCode] Multiply Strings 字符串相乘

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

随机推荐

  1. CSS3 子节点选择器

    CSS3中新增了几个子元素选择器,大大提高了开发者的开发效率.之前有些要通过为一个个子元素添加class,或者js实现才能实现的效果.现在可以很方便的用选择器实现. 这些新的样式已被现代浏览器及IE9 ...

  2. nodejs 事件机制

    node 事件机制   一 三种定时器 NodeJS中有三种类型的定时器:超时时间.时间间隔.即时定时器 1.超时时间:setTimeout(callback,delayMilliSeconds,[a ...

  3. lunix安装

    https://www.cnblogs.com/wcwen1990/p/7630545.html

  4. linux常用的命令之一chmod

    用权限 : 所有使用者 使用方式 : chmod [-cfvR] [--help] [--version] mode file... u 表示该档案的拥有者,g 表示与该档案的拥有者属于同一个群体(g ...

  5. 2019年猪年海报PSD模板-第五部分

    14套精美猪年海报,免费猪年海报,下载地址:百度网盘,https://pan.baidu.com/s/1CuZKPmFbbSBvzSXoCt2few                

  6. ElasticSearch搜索引擎安装配置拼音插件pinyin

    近几篇ElasticSearch系列: 1.阿里云服务器Linux系统安装配置ElasticSearch搜索引擎 2.Linux系统中ElasticSearch搜索引擎安装配置Head插件 3.Ela ...

  7. VS2015 更改C++模式

    亲爱的小伙伴,有没有发现你们的VS2015装完以后和老江湖们用的不一样了,人家的界面打开是这样的 而你的界面打开是这样的 虽然看是只有一左一右的区别,但是内在确实有好多不一样. 想不想想老江湖一样,拥 ...

  8. JMeter自学笔记3-创建自己的第一个测试用例

    一.写在前面的话: 上篇我们已经认识了JMeter的图形界面,大家应该都是很懵的.那么这篇,我们将学习使用JMeter创建第一个属于自己测试用例. 二.创建自己的第一个测试用例: 1.新建一个Thre ...

  9. 初涉 JavaScript

    网页是什么 网页 = Html+CSS+JavaScriptHtml:网页元素内容CSS:控制网页样式JavaScript:操作网页内容,实现功能或者效果 JavaScirpt 发展历史 参考 使用 ...

  10. 饥饿的小易(枚举+广度优先遍历(BFS))

    题目描述 小易总是感觉饥饿,所以作为章鱼的小易经常出去寻找贝壳吃.最开始小易在一个初始位置x_0.对于小易所处的当前位置x,他只能通过神秘的力量移动到 4 * x + 3或者8 * x + 7.因为使 ...