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. [javaSE] 并发编程(线程间通信)

    新建一个资源类Resource 定义成员变量String name 定义成员变量int age 新建一个输入类Input,实现Runnable接口 定义一个构造方法Input(),传入参数:Resou ...

  3. JSP学习笔记(5)-Java Servlet

    1.什么是Servlet? Servlet(Servlet Applet),全程Java Servlet,是用Java编写的服务器端程序,其主要功能在于交互式地浏览和修改数据,生成动态WEB内容.侠义 ...

  4. 转:导出csv文件数字会自动变科学计数法的解决方法

    导出csv文件数字会自动变科学计数法的解决方法   其实这个问题跟用什么语言导出csv文件没有关系.Excel显示数字时,如果数字大于12位,它会自动转化为科学计数法:如果数字大于15位,它不仅用于科 ...

  5. ArcGIS10.3+Oracle12C+ArcGIS Server10.3安装布署(之一)

    1.安装Oracle12C 2.配置Oracle12C的PDB监听(1)原始listener.ora文件 改为: (2)原始tnsnames.ora文件 改为: 3.连接Oracle12C的PDB数据 ...

  6. eval解析json字符串

    场景:在springMVC,手动拼接的list,转成本json字符串后,传到前台, 解决:需要解析成json对象,获取对象的属性,动态生成table. 首先,以下是后台准备好的list,list中有两 ...

  7. SQL Server ->> 条件筛选做法之 -- IN(VALUE1,VALUE2,...)与INNER JOIN STRING_SPLIT()性能对比

    在以逗号拼接而成的字符串,传入给IN字句的元素字符串中包涵了1400多个元素 两种做法分别为 AND e.ssPfCityId IN ( SELECT CAST(value AS INT) FROM ...

  8. 使用AHKActionSheet

    使用AHKActionSheet https://github.com/fastred/AHKActionSheet 基本配置代码: AHKActionSheet *actionSheet = [[A ...

  9. 我们是如何拿下Google和Facebook Offer的?

    http://posts.careerengine.us/p/57c3a1c1a09633ee7e57803c 大家好,我是小高,CMU CS Master,来Offer第一期学员,2014年初在孙老 ...

  10. IE漏洞的调试心得

    在调试漏洞的过程中,个人感觉最棘手的就是ie浏览器的漏洞和flash player的漏洞了.这里打算记录一下学习过程中的心得(主要是基于uaf类),以方便新人学习. 首先,ie漏洞与众不同的是,程序的 ...