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 带有通配符的字符串匹配问题. 设模式串为 ...
随机推荐
- 三菱蓝瑟CK4A
日本JDM蓝瑟,而且还是MR的性能版,避震行程也是这么长的.证明这个车子就是这样设计的. 90年代拉力血统的车就这样? 东南厂国产的蓝瑟,原装避震是厦门开发生产,来自于台湾开发工业集团的全资子公司,而 ...
- javaweb中的乱码问题
0.为什么需要编码,解码, 无论是图片,文档,声音,在网络IO,磁盘io中都是以字节流的方式存在及传递的,但是我们拿到字节流怎么解析呢?这句话就涉及了编码,解码两个过程,从字符数据转化为字节数据就是编 ...
- Shell-4--环境变量
- java后端导入excel模板和导入excel文件去读数据
模板转载地址:https://www.cnblogs.com/zhangyangtao/p/9802948.html 直接上代码(我是基于ssm写的demo,导入文件目前只能读取.xls后缀的exce ...
- Win10下音频设备无法播放音乐问题定位
最近一直在调试音频设备,由于音频设备需要在不同的采样率下面转换,所以会经常导致我的win10无法播放和录音. 刚开始在网上搜了相关的知识,但是一直没找到有效的解决方案.后来,无奈之下,使用了微软的声音 ...
- 记hangfire后台任务运行一段时间后不运行了。
什么是Hangfire Hangfire 是一个开源的.NET任务调度框架,目前1.6+版本已支持.NET Core.个人认为它最大特点在于内置提供集成化的控制台,方便后台查看及监控. https:/ ...
- 求一个集合的所有真子集 Python
给定一个集合,元素均为正整数且不重复,求该集合的所有子集 # -*- coding: utf-8 -*- """ Created on Tue Oct 10 09:04: ...
- 死磕 java集合之ArrayDeque源码分析
问题 (1)什么是双端队列? (2)ArrayDeque是怎么实现双端队列的? (3)ArrayDeque是线程安全的吗? (4)ArrayDeque是有界的吗? 简介 双端队列是一种特殊的队列,它的 ...
- mysql 开发进阶篇系列 41 mysql日志之慢查询日志
一.概述 慢查询日志记录了所有的超过sql语句( 超时参数long_query_time单位 秒),获得表锁定的时间不算作执行时间.慢日志默认写入到参数datadir(数据目录)指定的路径下.默认文件 ...
- jxl 读取xls,并转为二维数组可进行保存
jxl.jar: 通过java操作excel表格的工具类库 支持Excel 95-2000的所有版本 生成Excel 2000标准格式 支持字体.数字.日期操作 能够修饰单元格属性 支持图像和图表 应 ...