Description

很久很久以前,在你刚刚学习字符串匹配的时候,有两个仅包含小写字母的字符串A和B,其中A串长度为m,B串长度为n。可当你现在再次碰到这两个串时,这两个串已经老化了,每个串都有不同程度的残缺。
你想对这两个串重新进行匹配,其中A为模板串,那么现在问题来了,请回答,对于B的每一个位置i,从这个位置开始连续m个字符形成的子串是否可能与A串完全匹配?

Input

第一行包含两个正整数m,n(1<=m<=n<=300000),分别表示A串和B串的长度。
第二行为一个长度为m的字符串A。
第三行为一个长度为n的字符串B。
两个串均仅由小写字母和*号组成,其中*号表示相应位置已经残缺。

Output

第一行包含一个整数k,表示B串中可以完全匹配A串的位置个数。
若k>0,则第二行输出k个正整数,从小到大依次输出每个可以匹配的开头位置(下标从1开始)。

Sample Input

3 7
a*b
aebr*ob

Sample Output

2
1 5

Solution

FFT好神啊还能做字符串的题(逃
 

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N (1200000+1000)
using namespace std; double pi=acos(-1.0),F[N];
int n,m,fn,l,r[N],A[N],B[N];
int ans_num,ans[N];
char stA[N],stB[N];
struct complex
{
double x,y;
complex (double xx=,double yy=)
{
x=xx; y=yy;
}
}a[N],b[N]; complex operator + (complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
complex operator - (complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
complex operator * (complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
complex operator / (complex a,double b){return complex(a.x/b,a.y/b);} void FFT(int n,complex *a,int opt)
{
for (int i=; i<n; ++i)
if (i<r[i])
swap(a[i],a[r[i]]);
for (int k=; k<n; k<<=)
{
complex wn=complex(cos(pi/k),opt*sin(pi/k));
for (int i=; i<n; i+=k<<)
{
complex w=complex(,);
for (int j=; j<k; ++j,w=w*wn)
{
complex x=a[i+j], y=w*a[i+j+k];
a[i+j]=x+y; a[i+j+k]=x-y;
}
}
}
if (opt==-) for (int i=; i<n; ++i) a[i]=a[i]/n;
} int main()
{
scanf("%d%d",&m,&n);
scanf("%s%s",stA+,stB+);
for (int i=; i<=m; ++i) A[m-i+]=(stA[i]=='*')?:stA[i]-'a'+;
for (int i=; i<=n; ++i) B[i]=(stB[i]=='*')?:stB[i]-'a'+;
m++; n++;//因为我是字符串AB都向右移了一位,则计算出来的答案应该是向右移动两位的,故这里要+1 fn=;
while (fn<=n+m) fn<<=,l++;
for (int i=; i<fn; ++i)
r[i]=(r[i>>]>>) | ((i&)<<(l-)); memset(a,,sizeof(a)); memset(b,,sizeof(b));
for (int i=; i<=n; ++i)
a[i].x=A[i]*A[i]*A[i],b[i].x=B[i];
FFT(fn,a,); FFT(fn,b,);
for (int i=; i<=fn; ++i)
a[i]=a[i]*b[i];
FFT(fn,a,-);
for (int i=; i<=n; ++i)
F[i]+=a[i].x; memset(a,,sizeof(a)); memset(b,,sizeof(b));
for (int i=; i<=n; ++i)
a[i].x=A[i]*A[i],b[i].x=B[i]*B[i];
FFT(fn,a,); FFT(fn,b,);
for (int i=; i<=fn; ++i)
a[i]=a[i]*b[i];
FFT(fn,a,-);
for (int i=; i<=n; ++i)
F[i]-=*a[i].x; memset(a,,sizeof(a)); memset(b,,sizeof(b));
for (int i=; i<=n; ++i)
a[i].x=A[i],b[i].x=B[i]*B[i]*B[i];
FFT(fn,a,); FFT(fn,b,);
for (int i=; i<=fn; ++i)
a[i]=a[i]*b[i];
FFT(fn,a,-);
for (int i=; i<=n; ++i)
F[i]+=a[i].x; for (int i=m; i<=n; ++i) if ((int)(F[i]+0.5)==) ans[++ans_num]=i-m+;
printf("%d\n",ans_num);
for (int i=; i<ans_num; ++i) printf("%d ",ans[i]);
printf("%d",ans[ans_num]);
}

BZOJ4259:残缺的字符串(FFT)的更多相关文章

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

    题意 题目链接 Sol 知道FFT能做字符串匹配的话这就是个裸题了吧.. 考虑把B翻转过来,如果\(\sum_{k = 0}^M (B_{i - k} - A_k)^2 * B_{i-k}*A_k = ...

  2. luoguP4173 残缺的字符串 FFT

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

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

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

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

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

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

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

  6. BZOJ 4259: 残缺的字符串 [FFT]

    4259: 残缺的字符串 题意:s,t,星号任意字符,匹配方案数 和上题一样 多乘上一个\(a_{j+i}\)就行了 #include <iostream> #include <cs ...

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

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

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

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

  9. BZOJ4259 残缺的字符串(FFT)

    两个串匹配时相匹配的位置位置差是相同的,那么翻转一个串就变成位置和相同,卷积的形式. 考虑如何使用卷积体现两个位置能否匹配.一个暴力的思路是每次只考虑一种字符,将其在一个串中设为1,并在另一个串中将不 ...

随机推荐

  1. eclipse/myEclipse 代码提示和快捷键

    一.设置自动提示 设置eclipse/myEclipse代码提示可以方便开发者,不用在记住拉杂的单词,只用打出首字母,就会出现提示代码菜单. 1.菜单window->Preferences-&g ...

  2. Qt程序Release版出现 类似 QEventLoop: Cannot be used without QApplication 问题的终极解决方案

    最近在做Qt程序开发,程序在Debug下跑是没有问题的,发布到Release版本后,出现各种问题: 报各种莫名其妙的错误,类似的错误有:   QEventLoop:Cannot be used wit ...

  3. 3D旋转效果

    <!doctype html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  4. h5笔记

    标签 更语义化标签 header标签 nav标签 section标签 article标签 aside标签 widget标签 footer标签 为什么要有语义化标签 能够便于开发者阅读和写出更优雅的代码 ...

  5. ionic开发中遇到的问题

    开发调试过程中,会遇到这样的问题:同源策略请求url禁止请求. 一   网上搜的结果基本是2类: 1. 同源策略请求被阻止, 跨域问题,大家建议添加Access-Control-Allow-Origi ...

  6. Android开发问题积累 <加载在线Gif><WebView无法加载网页图片>

    在线Gif加载 解决办法 Glide完美解决 Glide.with(context).load(pic).placeholder(R.drawable.loading).into(imageView) ...

  7. Maven + Spring4

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  8. MVP 模式简单易懂的介绍方式

    为什么用Android MVP 设计模式? 当项目越来越庞大.复杂,参与的研发人员越来越多的时候,MVP 模式 的优势就充分显示出来了. MVP 模式是 MVC 模式在 Android 上的一种变体, ...

  9. 类和类的关系——java

    类(对象)之间的关系   1.继承关系(子类自动拥有了父类所有的成员变量和普通方法,如果父类的成员变量和普通方法是private 的,那么子类只有拥有权,没有使用权.父类的构造方法在子类的构造方法执行 ...

  10. gearman入门初步

    原文地址:http://blog.sina.com.cn/s/blog_5f54f0be0101btsi.html     PHP 没有提供直接的并发功能.要实现并发,必须: function asy ...