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 带有通配符的字符串匹配问题. 设模式串为 ...
随机推荐
- Javascript高级编程学习笔记(7)—— 函数
前几天有事耽搁了,今天继续更新 今天的主要内容是JS中的函数 这一篇主要讲函数的定义等内容,至于变量提升.执行环境.闭包.内存回收等内容在后面讲,高玩们可以不用看下面的正文了. 函数 首先来讲,函数对 ...
- js中数字直接点方法会报错,如1.toString()
Number(11).toString() "11" var num = 111; undefined num.toString() "111" .toStri ...
- 记一次sentry部署过程
本文记录下部署sentry和其中遇到的问题 Sentry 是一款基于 Django实现的错误日志收集和聚合的平台,它是 Python 实现的,但是其日志监控功能却不局限于python,对诸如 Node ...
- 剑指offer【02】- 替换空格(Java)
题目:替换空格 考点:字符串 题目描述: 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. ...
- 如何在Mac下配置Github和Bitbucket的SSH
--- title: 如何在Mac下配置Github和Bitbucket的SSH date: 2017-12-23 21:10:30 tags: - Mac - Git - Github catego ...
- (转)mtr命令详解诊断网络路由
原文:https://blog.51cto.com/6226001001/1941355 http://www.zzbiji.com/2212.html----Linux下使用mtr做路由图进行网络分 ...
- rsync实现目录同步
rsync rsync是linux系统下的数据镜像备份工具.使用快速增量备份工具Remote Sync可以远程同步,支持本地复制,或者与其他SSH.rsync主机同步. 外文名 rsync 全 ...
- 深入浅出分析MySQL MyISAM与INNODB索引原理、优缺点分析
本文浅显的分析了MySQL索引的原理及针对主程面试的一些问题,对各种资料进行了分析总结,分享给大家,希望祝大家早上走上属于自己的"成金之路". 学习知识最好的方式是带着问题去研究所 ...
- mysql 开发进阶篇系列 40 mysql日志之二进制日志下以及查询日志
一.binlog 二进制其它选项 在二进制日志记录了数据的变化过程,对于数据的完整性和安全性起着非常重要作用.在mysql中还提供了一些其它参数选项,来进行更小粒度的管理. 1.1 binlog-do ...
- vector、deque、stack、queue、list以及set的使用
注意:以下测试案例都要加上相应的头文件,必要时要加上algorithm文件. 1.vector 连续存储结构,每个元素在内存上是连续的:支持高效的随机访问和在尾端插入/删除操作,但其他位置的插入/删除 ...