CF1202E You Are Given Some Strings...
题意简述:给出 \(t\) 与 \(s_{1,2,\cdots,n}\)。求对于所有 \(i,j\in[1,n]\),\(s_i+s_j\) 在 \(t\) 中出现次数之和。
如果只有 \(s_i\) 那么显然是 ACAM 的板子题,对每个位置 \(p\) 记录它的前缀的所有后缀能与多少 \(s_i\) 相等,即为 \(a_p\)(即有多少 \(i\) 满足 \(t[p-|s_i|+1:p]=s_i\)。实际上就是该位置前缀 \(t[1:p]\) 在 ACAM 上跑到的位置在 fail 树上与根的路径上有多少 \(s_i\) 的终止节点)。如果再加上 \(s_j\),就要求一个位置的后缀有多少与 \(s_j\) 相等的前缀,即为 \(b_p\)。那么可以建 \(s\) 所有反串的 ACAM,再用 \(t\) 的反串上去跑即可。根据乘法原理,答案为 \(\sum a_ib_{i+1}\)。
时间复杂度为字符总长度乘以字符集大小。
/*
Powered by C++11.
Author : Alex_Wei.
*/
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define all(x) x.begin(),x.end()
#define rev(x) reverse(all(x))
const int N=2e5+5;
const int S=26;
struct ACAM{
int cnt,f[N],son[N][S],ed[N];
void ins(string s){
int p=0;
for(char it:s){
if(!son[p][it-'a'])son[p][it-'a']=++cnt;
p=son[p][it-'a'];
} ed[p]++;
} void build(){
queue <int> q;
for(int i=0;i<26;i++)if(son[0][i])q.push(son[0][i]);
while(!q.empty()){
int t=q.front(); q.pop();
for(int i=0;i<26;i++)
if(son[t][i])f[son[t][i]]=son[f[t]][i],q.push(son[t][i]);
else son[t][i]=son[f[t]][i];
ed[t]+=ed[f[t]];
}
}
}a,b;
ll n,ans,s[N];
string t;
int main(){
cin>>t>>n;
for(int i=1;i<=n;i++){
string s; cin>>s;
a.ins(s),rev(s),b.ins(s);
} a.build(),b.build();
for(int i=1,p=0;i<=t.size();i++)
p=a.son[p][t[i-1]-'a'],s[i]=a.ed[p];
for(int i=t.size(),p=0;i;i--)
p=b.son[p][t[i-1]-'a'],ans+=s[i-1]*b.ed[p];
cout<<ans<<endl;
return 0;
}
CF1202E You Are Given Some Strings...的更多相关文章
- ACAM 题乱做
之前做了不少 ACAM,不过没怎么整理起来,还是有点可惜的. 打 * 的是推荐一做的题目. I. *CF1437G Death DBMS 见 我的题解. II. *CF1202E You Are Gi ...
- 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 ...
随机推荐
- 什么是Sprint计划?
Sprint 计划是Scrum框架中的一个事件,团队将确定他们将在冲刺期间处理的产品积压项目,并讨论他们完成这些产品积压项目的初始计划. 团队可能会发现建立冲刺目标很有帮助,并以此为基础确定他们在冲刺 ...
- mybatis中的#和$的区别 以及 防止sql注入
声明:这是转载的. mybatis中的#和$的区别 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sq ...
- netty中使用protobuf实现多协议的消息
在我们使用 netty 的过程中,有时候为了高效的传输数据,经常使用 protobuf 进行数据的传输,netty默认情况下为我们实现的 protobuf 的编解码,但是默认的只能实现单个对象的编解码 ...
- Elasticsearch核心技术(三):Mapping设置
本文从Mapping简介.Dynamic Mapping.自定义Mapping和Mapping常用参数说明4个部分介绍Elasticsearch如何设置Mapping. 3.1 Mapping简介 3 ...
- TensorFlow从入门到入坑(2)
TensorFlow学习(2) 一.jupyter notebook的安装和使用 1. 什么是jupyter notebook jupyter notebook(http://jupyter.org/ ...
- linux下使用shell命令通过wpa_cli控制wpa_supplicant连接wifi
最近在调试wifi,已经把wpa_supplicant 工具编译打包好了,为了测试wif驱动及wifi模块是否ok,需要用shell命令临时启动wifi服务连接wifi热点测试. 首先板子启动用ifc ...
- distinct-subsequences leetcode C++
Given a string S and a string T, count the number of distinct subsequences of T in S. A subsequence ...
- mysql登录后重置root密码的步骤
mysql重置root密码. 方法一: 编辑配置文件 /etc/my.cnf ,在[mysqld]后面任意一行添加"skip-grant-tables"用来跳过密码验证 接下来我们 ...
- Dataworks批量刷数优化方案探讨
Dataworks批量刷数优化方案探讨 在数据仓库的日常使用中,经常会有批量补数据,或者逻辑调整后批量重跑数据的场景. 批量刷数的实现方式,因调度工具差异而各有不同. Dataworks调度批量刷数局 ...
- 小入门 Django(做个疫情数据报告)
Django 是 Python web框架,发音 [ˈdʒæŋɡo] ,翻译成中文叫"姜狗". 为什么要学框架?其实我们自己完全可以用 Python 代码从0到1写一个web网站, ...