BZOJ4259: 残缺的字符串(FFT 字符串匹配)
题意
Sol
知道FFT能做字符串匹配的话这就是个裸题了吧。。
考虑把B翻转过来,如果\(\sum_{k = 0}^M (B_{i - k} - A_k)^2 * B_{i-k}*A_k = 0\)
那么说明能匹配。然后拆开三波FFT就行了
/*
*/
#include<bits/stdc++.h>
#define LL long long
const int MAXN = 1e6 + 10, INF = 1e9 + 7;
using namespace std;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, M;
LL g[MAXN], f[MAXN];
char sa[MAXN], sb[MAXN];
int ta[MAXN], tb[MAXN], a[MAXN], b[MAXN], rev[MAXN], lim;
LL sqr2(int x) {return 1ll * x * x;}
LL sqr3(int x) {return 1ll * x * x * x;}
const double PI = acos(-1);
struct com {
double x, y;
com operator * (const com &rhs) const {
return {x * rhs.x - y * rhs.y, x * rhs.y + y * rhs.x};
}
com operator + (const com &rhs) const {
return {x + rhs.x, y + rhs.y};
}
com operator - (const com &rhs) const {
return {x - rhs.x, y - rhs.y};
}
}A[MAXN], B[MAXN];
void FFT(com *A, int lim, int type) {
for(int i = 0; i < lim; i++) if(i < rev[i]) swap(A[i], A[rev[i]]);
for(int mid = 1; mid < lim; mid <<= 1) {
com wn = {cos(PI / mid), type * sin(PI / mid)};
for(int i = 0; i < lim; i += (mid << 1)) {
com w = {1, 0};
for(int j = 0; j < mid; j++, w = w * wn) {
com x = A[i + j], y = w * A[i + j + mid];
A[i + j] = x + y;
A[i + j + mid] = x - y;
}
}
}
if(type == -1) {
for(int i = 0; i <= lim; i++) A[i].x /= lim;
}
}
void mul(int *b, int *a) {
memset(A, 0, sizeof(A)); memset(B, 0, sizeof(B));
for(int i = 0; i < N; i++) B[i].x = b[i];
for(int i = 0; i < M; i++) A[i].x = a[i];
FFT(B, lim, 1);
FFT(A, lim, 1);
for(int i = 0; i < lim; i++) B[i] = B[i] * A[i];
FFT(B, lim, -1);
for(int i = M - 1; i <= N; i++)
f[i] += round(B[i].x);
}
signed main() {
//freopen("2.in", "r", stdin); freopen("b.out", "w", stdout);
M = read(); N = read();
scanf("%s %s", sa, sb);
for(int i = 0; i < M; i++) ta[i] = (sa[i] == '*' ? 0 : sa[i] - 'a' + 1);
for(int i = 0; i < N; i++) tb[i] = (sb[i] == '*' ? 0 : sb[i] - 'a' + 1);
reverse(tb, tb + N);
int len = 0; lim = 1;
while(lim <= N + M) len++, lim <<= 1;
for(int i = 0; i < lim; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << len - 1);
for(int i = 0; i < N; i++) b[i] = sqr3(tb[i]);
for(int i = 0; i < M; i++) a[i] = ta[i];
mul(b, a);
for(int i = 0; i < N; i++) b[i] = -2 * sqr2(tb[i]);
for(int i = 0; i < M; i++) a[i] = sqr2(ta[i]);
mul(b, a);
for(int i = 0; i < N; i++) b[i] = tb[i];
for(int i = 0; i < M; i++) a[i] = sqr3(ta[i]);
mul(b, a);
int ans = 0;
for(int i = M - 1; i < N; i++)
if(!f[i]) ans++;
printf("%d\n", ans);
for(int i = N - 1; i >= M - 1; i--)
if(!f[i])
printf("%d ", N - i);
return 0;
}
/*
3 7
a*b
aebr*ob
*/
BZOJ4259: 残缺的字符串(FFT 字符串匹配)的更多相关文章
- P4173 残缺的字符串(FFT字符串匹配)
P4173 残缺的字符串(FFT字符串匹配) P4173 解题思路: 经典套路将模式串翻转,将*设为0,设以目标串的x位置匹配结束的匹配函数为\(P(x)=\sum^{m-1}_{i=0}[A(m-1 ...
- BZOJ4259:残缺的字符串(FFT)
Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同 ...
- Luogu P4173 残缺的字符串-FFT在字符串匹配中的应用
P4173 残缺的字符串 FFT在字符串匹配中的应用. 能解决大概这种问题: 给定长度为\(m\)的A串,长度为\(n\)的B串.问A串在B串中的匹配数 我们设一个函数(下标从\(0\)开始) \(C ...
- luoguP4173 残缺的字符串 FFT
luoguP4173 残缺的字符串 FFT 链接 luogu 思路 和昨天做的题几乎一样. 匹配等价于(其实我更喜欢fft从0开始) \(\sum\limits_{i=0}^{m-1}(S[i+j]- ...
- 【BZOJ4259】残缺的字符串 FFT
[BZOJ4259]残缺的字符串 Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时, ...
- BZOJ4259 残缺的字符串 【fft】
题目 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想 ...
- BZOJ4259残缺的字符串
题目描述 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. ...
- CF528D Fuzzy Search 和 BZOJ4259 残缺的字符串
Fuzzy Search 给你文本串 S 和模式串 T,求 S 的每个位置是否能模糊匹配上 T. 这里的模糊匹配指的是把 T 放到 S 相应位置上之后,T 中每个字符所在位置附近 k 个之内的位置上的 ...
- 洛谷 P4173 残缺的字符串 (FFT)
题目链接:P4173 残缺的字符串 题意 给定长度为 \(m\) 的模式串和长度为 \(n\) 的目标串,两个串都带有通配符,求所有匹配的位置. 思路 FFT 带有通配符的字符串匹配问题. 设模式串为 ...
随机推荐
- 学习在dos下使用gcc来编译
这两年里,断断续续的学习和使用c,平时都是在CodeBlocks里写代码,编译程序,点一下按钮就行了.对整个编译过程是一点儿都不了解.相比当年学习java,真的是选择了两个不同的路,当年学习java的 ...
- zabbix docker - 安装和初始化配置
zabbix docker - 安装和初始化配置 安装zabbix server docker-mysql版本 zabbix server支持不同的数据库(详见zabbix的docker hub),这 ...
- 聚簇索引(clustered index )和非聚簇索引(secondary index)的区别
这两个名字虽然都叫做索引,但这并不是一种单独的索引类型,而是一种数据存储方式.对于聚簇索引存储来说,行数据和主键B+树存储在一起,辅助键B+树只存储辅助键和主键,主键和非主键B+树几乎是两种类型的树. ...
- 使用 mybatis-generator 自动生成 MyBatis 代码
首先把这三个文件放到一个目录里,我是放到了C盘下的wangbo目录下: 接下来就是设置config.xml文件了,config.xml: <?xml version="1.0" ...
- SVN 客户端 TortoiseSVN 的安装和使用
关于 参考博客:TortoiseSVN新人使用指南 TortoiseSVN 是一个 Apache Subversion(SVN)客户端,实现为Windows外壳扩展.它直观且易于使用,因为它不需要Su ...
- 【微服务】.netCore eShopOnContainers 部署实践《一》
官方说明文档 -------------------------------------------------------------- # eShopOnContainers - Microser ...
- django配置celery
官网详尽的django结合celery的配置步骤 在django项目settings.py所在的目录中新建一个celery.py,内容如下 from __future__ import absolut ...
- JavaScript中原型链的那些事
引言 在面向对象的语言中继承是非常重要的概念,许多面向对象语言都支持两种继承方式:接口继承和实现继承.接口继承制只继承方法签名,而实现继承继承实际的方法.在ECMAScript中函数没有签名,所以EC ...
- css选择符权重
css选择符权重 目录 css选择符权重 css选择器权重列表 CSS选择符冲突处理 css选择符权重 css选择器权重列表 选择器 权重 内联样式 1000 ID 0100 CLASS 0010 属 ...
- Centos 7 安装 rabbitmq
1.安装erlang rabbitmq 官方下载地址 "http://www.rabbitmq.com/download.html" ,选择"RHEL, CentOS, ...