题目描述

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

你想对这两个串重新进行匹配,其中A为模板串,那么现在问题来了,请回答,对于B的每一个位置i,从这个位置开始连续m个字符形成的子串是否可能与A串完全匹配?

题解

带通配符的字符串匹配问题。

我们先把通配符设为0,考虑如果匹配串中的一段和模式串完全匹配,那么必然满足∑(a[i]-b[i])^2*a[i]*b[i]=0。

很容易发现这是个卷积,那么把任意一个串倒过来FFT一下就好了。

这题还卡我精度。。。

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define N 600002
#define double long double
using namespace std;
typedef long long ll;
int l,L,n,m,rev[N],ans[N];
char s1[N],s2[N];
const double pai=acos(-1.0);
struct fs{
double x,y;
fs(double xx=,double yy=){x=xx;y=yy;}
fs operator +(const fs &b)const{return fs{x+b.x,y+b.y};}
fs operator -(const fs &b)const{return fs{x-b.x,y-b.y};}
fs operator *(const fs &b)const{return fs{x*b.x-y*b.y,x*b.y+y*b.x};}
}a[N],b[N],c[N],d[N],e[N];
inline void FFT(fs *a,int tag){
for(int i=;i<l;++i)if(i>rev[i])swap(a[i],a[rev[i]]);
for(int i=;i<l;i<<=){
fs wn(cos(pai/i),tag*sin(pai/i));
for(int j=;j<l;j+=(i<<)){
fs w(,);
for(int k=;k<i;++k,w=w*wn){
fs x=a[j+k],y=a[i+j+k]*w;
a[j+k]=x+y;a[i+j+k]=x-y;
}
}
}
}
int main(){
scanf("%d%d",&m,&n);
l=;L=;
while(l<n)l<<=,L++;
for(int i=;i<l;++i)rev[i]=(rev[i>>]>>)|((i&)<<(L-));
scanf("%s%s",s2,s1);
for(int i=;i<n;++i)if(s1[i]=='*')s1[i]=;else s1[i]-='A';
for(int i=;i<m;++i)if(s2[i]=='*')s2[i]=;else s2[i]-='A';
reverse(s2,s2+m);
for(int i=;i<n;++i)a[i].x=1ll*s1[i]*s1[i]*s1[i];
for(int i=;i<m;++i)b[i].x=s2[i];
FFT(a,);FFT(b,);
for(int i=;i<l;++i)c[i]=a[i]*b[i];
FFT(c,-);
for(int i=;i<l;++i)c[i].x=(ll)(c[i].x/l+0.4);
memset(a,,sizeof(a));memset(b,,sizeof(b));
for(int i=;i<n;++i)a[i].x=s1[i]*s1[i];
for(int i=;i<m;++i)b[i].x=s2[i]*s2[i];
FFT(a,);FFT(b,);
for(int i=;i<l;++i)d[i]=a[i]*b[i]*fs(,);
FFT(d,-);
for(int i=;i<l;++i)d[i].x=(ll)(d[i].x/l+0.4);
memset(a,,sizeof(a));memset(b,,sizeof(b));
for(int i=;i<n;++i)a[i].x=s1[i];
for(int i=;i<m;++i)b[i].x=1ll*s2[i]*s2[i]*s2[i];
FFT(a,);FFT(b,);
for(int i=;i<l;++i)e[i]=a[i]*b[i];
FFT(e,-);
for(int i=;i<l;++i)e[i].x=(ll)(e[i].x/l+0.4);
for(int i=m-;i<n;++i)if(c[i].x+e[i].x-d[i].x==)ans[++ans[]]=i-m+;
printf("%d\n",ans[]);
for(int i=;i<=ans[];++i)printf("%d ",ans[i]);
return ;
}

BZOJ4259残缺的字符串的更多相关文章

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

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

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

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

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

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

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

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

  5. BZOJ4259: 残缺的字符串 & BZOJ4503: 两个串

    [传送门:BZOJ4259&BZOJ4503] 简要题意: 给出两个字符串,第一个串长度为m,第二个串长度为n,字符串中如果有*字符,则代表当前位置可以匹配任何字符 求出第一个字符串在第二个字 ...

  6. BZOJ4259 残缺的字符串 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8798532.html 题目传送门 - BZOJ4259 题意 给你两个串,用其中一个来匹配另一个.问从母串的那些 ...

  7. [BZOJ4259]残缺的字符串

    Description: 给定两个带通配符的串,求可能出现几次匹配,以及这些匹配位置 Hint: \(n \le 3*10^5\) Solution: 定义匹配函数 \(P(x)=\sum_{i=x} ...

  8. 2018.11.17 bzoj4259: 残缺的字符串(fft)

    传送门 fftfftfft套路题. 我们把aaa ~ zzz映射成111 ~ 262626,然后把∗*∗映射成000. 考虑对于两个长度都为nnn的字符串A,BA,BA,B. 我们定义一个差异函数di ...

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

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

随机推荐

  1. 二、IPC机制

    1.Android IPC简介 IPC是Inter-Process Communication的缩写,含义为进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程. ANR:Applicatio ...

  2. leetcode-48.旋转图像

    leetcode-48.旋转图像 point: 数组 题意 给定一个 n × n 的二维矩阵表示一个图像. 将图像顺时针旋转 90 度. 说明: 你必须在原地旋转图像,这意味着你需要直接修改输入的二维 ...

  3. 从头认识一下docker-附带asp.net core程序的docker化部署

    从头认识一下docker-附带asp.net core程序的docker化部署 简介 在计算机技术日新月异的今天, Docker 在国内发展的如火如荼,特别是在一线互联网公司, Docker 的使用是 ...

  4. MongoDB 聚合分组取第一条记录的案例及实现

    关键字:MongoDB: aggregate:forEach 今天开发同学向我们提了一个紧急的需求,从集合mt_resources_access_log中,根据字段refererDomain分组,取分 ...

  5. Linux创建和挂载XFS文件系统测试实践

    XFS文件系统简介 维基百科关于XFS的简介如下: XFS is a high-performance 64-bit 年,由Silicon Graphics为他们的IRIX操作系统而开发,是IRIX ...

  6. mysql5.7不支持group by的解决办法

    1.查看sql_mode select @@global.sql_mode 查询出来的值为: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DAT ...

  7. 聚类——GMM

    聚类——认识GMM算法 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 一.GMM概述 二.GMM算法步骤 三.具体推导参考文献 1. 李航. 统计学习 ...

  8. html+css 制作简易导航栏

    二话不说直接上代码(萌新:实在也没什么好说的) <!DOCTYPE html> <html lang="en" xmlns="http://www.w3 ...

  9. Building Lambda Architecture with Spark Streaming

    The versatility of Apache Spark’s API for both batch/ETL and streaming workloads brings the promise ...

  10. 关于Docker开通远程访问端口2375

    一.使用版本:docker for windows 18.06,安装过程略,具体如下: 二.开通远程访问端口2375,只需要设置一下即可,如下图: