[CF452E]Three strings
题目大意:给你三个字符串$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的更多相关文章
- CF452E Three strings 广义后缀自动机
建一个广义后缀自动机统计一下就行,好长时间不敲后缀自动机调了半天~ #include <bits/stdc++.h> using namespace std; namespace IO { ...
- Hacker Rank: Two Strings - thinking in C# 15+ ways
March 18, 2016 Problem statement: https://www.hackerrank.com/challenges/two-strings/submissions/code ...
- 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 ...
- Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
- [LeetCode] Add Strings 字符串相加
Given two non-negative numbers num1 and num2 represented as string, return the sum of num1 and num2. ...
- [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 ...
- [LeetCode] Group Shifted Strings 群组偏移字符串
Given a string, we can "shift" each of its letter to its successive letter, for example: & ...
- [LeetCode] Isomorphic Strings 同构字符串
Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the chara ...
- [LeetCode] Multiply Strings 字符串相乘
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
随机推荐
- clr via c#读书笔记五:常量和字段
1.常量是值从不变化的符号.只能定义编译器识别的基元类型的常量.如:Boolean,Char,Byte,SByte,Int16,UInt16,Int32,UInt32,Int64,Single,Dou ...
- nio之netty5应用
1.netty5和netty4的区别不是很大,但是与netty3差别还是有的.这里不介绍netty4,因为和netty5的方式都差不多.netty5的复杂性相对于netty3要多很多了.基本上架构都被 ...
- springboot 读写excel
添加两个坐标: <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</a ...
- Python-特殊变量
from test import test ''' __mame__ __file__ __cache__ __package__ ''' # import os # 获取这个当前文件的绝对路径 # ...
- webpack loader 生成虚拟文件的方案
此文已由作者张磊授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 前言 使用 webpack 的时候,难免需要写一些 loader,接着就会遇到一个很纠结的问题.该 loade ...
- Qt listwigwt item 加入自定义元素
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255) ...
- Java开发工程师(Web方向) - 01.Java Web开发入门 - 第5章.Git
第5章--Git 版本控制简介 VCS (version control system) 版本控制系统:记录若干文件的修订记录的系统,帮助查阅/回到某个历史版本 LVCS本地 CVCS集中式(Cent ...
- Java学习 · 初识 多线程
多线程 1. 基础概念 a) 程序 Program i. 静态代码,指令集,应用程序执行的蓝本 b) 进程 Process i. 动态概念,正在运 ...
- [Clr via C#读书笔记]Cp7常量和字段
Cp7常量和字段 常量 常量在编译的时候必须确定,只能一编译器认定的基元类型.被视为静态,不需要static:直接嵌入IL中: 区别ReadOnly 只能在构造的时候初始化,内联初始化. 字段 数据成 ...
- [2018 ACL Short and System] 对话系统
Short Paper(s) 1. Task-oriented Dialogue System for Automatic Diagnosis. (Cited by 0) Zhongyu Wei, ...