题意

题目链接

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 字符串匹配)的更多相关文章

  1. P4173 残缺的字符串(FFT字符串匹配)

    P4173 残缺的字符串(FFT字符串匹配) P4173 解题思路: 经典套路将模式串翻转,将*设为0,设以目标串的x位置匹配结束的匹配函数为\(P(x)=\sum^{m-1}_{i=0}[A(m-1 ...

  2. BZOJ4259:残缺的字符串(FFT)

    Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同 ...

  3. Luogu P4173 残缺的字符串-FFT在字符串匹配中的应用

    P4173 残缺的字符串 FFT在字符串匹配中的应用. 能解决大概这种问题: 给定长度为\(m\)的A串,长度为\(n\)的B串.问A串在B串中的匹配数 我们设一个函数(下标从\(0\)开始) \(C ...

  4. luoguP4173 残缺的字符串 FFT

    luoguP4173 残缺的字符串 FFT 链接 luogu 思路 和昨天做的题几乎一样. 匹配等价于(其实我更喜欢fft从0开始) \(\sum\limits_{i=0}^{m-1}(S[i+j]- ...

  5. 【BZOJ4259】残缺的字符串 FFT

    [BZOJ4259]残缺的字符串 Description 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时, ...

  6. BZOJ4259 残缺的字符串 【fft】

    题目 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. 你想 ...

  7. BZOJ4259残缺的字符串

    题目描述 很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n.可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺. ...

  8. CF528D Fuzzy Search 和 BZOJ4259 残缺的字符串

    Fuzzy Search 给你文本串 S 和模式串 T,求 S 的每个位置是否能模糊匹配上 T. 这里的模糊匹配指的是把 T 放到 S 相应位置上之后,T 中每个字符所在位置附近 k 个之内的位置上的 ...

  9. 洛谷 P4173 残缺的字符串 (FFT)

    题目链接:P4173 残缺的字符串 题意 给定长度为 \(m\) 的模式串和长度为 \(n\) 的目标串,两个串都带有通配符,求所有匹配的位置. 思路 FFT 带有通配符的字符串匹配问题. 设模式串为 ...

随机推荐

  1. ZKWeb网页框架1.7正式发布

    1.7.0更新的内容有 更新项目格式到新的csproj 更新项目模板 打开新创建的Asp.Net Core项目将需要VS 2017,Asp.Net和Owin项目仍可以用VS 2015 补上插件模板的P ...

  2. Android开发 - 掌握ConstraintLayout(四)创建基本约束

    上一篇我们介绍了编辑器的基本使用,本文我们介绍创建基本的约束. "约束"表示View之间的位置关系.当我们在ConstraintLayout布局中创建View时,如果我们没有添加任 ...

  3. ACM知识点分类

    (知识点分类.看完想(╯‵□′)╯︵┻━┻) orz...一点点来吧.简单标记一下. 蓝色,比较熟悉,能够做. 蓝绿色,一般熟悉,需要加强 红色,(比个辣鸡.jpg) (标记完突然想打人...) 第一 ...

  4. 转---JS 一定要放在 Body 的最底部么?聊聊浏览器的渲染机制

    作者:德来 segmentfault.com/a/1190000004292479 如有好文章投稿,请点击 → 这里了解详情 一.从一个面试题说起 面试前端的时候我喜欢问一些看上去是常识的问题.比如: ...

  5. 从Redis生成数据表主键标识

    对于MySql的全局ID(主键),我们一般采用自增整数列.程序生成GUID.单独的表作为ID生成器,这几种方案各有优劣,最终效率都不能说十分理想(尤其海量数据下),其实通过Redis的INCR可以很方 ...

  6. iOS开发手记-仿QQ音乐播放器动态歌词的实现

    最近朋友想做个音乐App,让我帮忙参考下.其中歌词动态滚动的效果,正好我之前也没做过,顺便学习一下,先来个预览效果. 实现思路 歌词常见的就是lrc歌词了,我们这里也是通过解析lrc歌词文件来获取其播 ...

  7. 原生js实现vue组件功能

    在如今VUE盛行的情况下,我们一直在惊叹于VUE的组件的功能,却不知道,原生js早就已经支持了这个功能. 最近在公开课学到的,js还有很多很多需要探索学习. 下面是一个简单的例子 <!DOCTY ...

  8. 理解Array.prototype.fill和Array.from

    之所以将这两个方法放在一起说,是因为经常写这样的代码: Array.from({length: 5}).fill(0),看起来很简洁,但是踩到坑之后才发现自己对这两个方法实在是不求甚解. Array. ...

  9. python学习之切片

    所谓切片,其实是列表的部分元素——Python称之为切片.要创建切片,可指定要使用的第一个元素和最后一个元素的索引 . players = ['charles', 'martina', 'michae ...

  10. Android_Fragment和Activity之间的通信

    Fragment 的生命周期是随着activity变化而变化的. 如果activity要给在运行的时候给fragment传人数据则需要fragment实现一个自定义的接口,并且实现接口里面的方法,在a ...