题面

1684 -- 【BZOJ4259】残缺的字符串

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

题目分析

法一:

我们可以参考【BZOJ3160】万径人踪灭的做法,相当于求\(26\)组FFT,若和==长度即可。

然而,这样做相当于\(O(26n\log n)\),无法在1s内完成。


法二:

还是考虑FFT,我们能否改变状态,让他用更少的次数求出答案?

如果\(a_i,b_j\)要配上,要么\(a_i==b_j\),要么\(a_i==*||b_j==*\)。

当\(a_i==b_j\),有\((a_i-b_j)\)=0,

而当\(a_i==*||b_j==*​\),我们可以把\(*​\)的值设为\(0​\),所以有\(\displaystyle\sum_{i=1}^m(a_i-b_{j+i})\cdot a_i\cdot b_{j+i}==0​\),

但是,我们要考虑,\(a_i-b_{j+i}\)可正可负,

为了防止恰好和为\(0\),我们写作\(\displaystyle\sum_{i=1}^m(a_i-b_{j+i})^2\cdot a_i\cdot b_{j+i}==0\)

将\(b\)反转,可以写作与法一相似的卷积的形式,然后分别求解拼起来即可。

代码实现

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<iomanip>
#include<cstdlib>
#include<complex>
#define MAXN 0x7fffffff
typedef long long LL;
const int N=1100005;
using namespace std;
inline int Getint(){register int x=0,f=1;register char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}return x*f;}
typedef complex<double>Z;
const double pi=M_PI;
void FFT(Z *a,int x,int K){static int rev[N],lst;int n=1<<x;if(n!=lst){for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<x-1);lst=n;}for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);for(int i=1;i<n;i<<=1){int tmp=i<<1;Z wn(cos(pi/i),sin(pi*K/i));for(int j=0;j<n;j+=tmp){Z w(1,0);for(int k=0;k<i;k++,w=w*wn){Z x=a[j+k],y=w*a[i+j+k];a[j+k]=x+y;a[i+j+k]=x-y;}}}if(K==-1)for(int i=0;i<n;i++)a[i]/=n;
}
Z a[3][N],b[3][N],ans[N];
char A[N],B[N];
LL Get(Z x){return (LL)(x.real()+0.5);}
int st[N],top;
int main(){int m=Getint(),n=Getint();scanf("%s%s",A+1,B+1);reverse(A+1,A+1+m);for(int i=1;i<=m;i++){int x=(isalpha(A[i])?(A[i]-'a'+1):0);a[0][i].real()=x,a[1][i].real()=x*x,a[2][i].real()=x*x*x;}for(int i=1;i<=n;i++){int x=(isalpha(B[i])?(B[i]-'a'+1):0);b[0][i].real()=x,b[1][i].real()=x*x,b[2][i].real()=x*x*x;}int x=ceil(log2(m+n+3));FFT(a[0],x,1),FFT(a[1],x,1),FFT(a[2],x,1);FFT(b[0],x,1),FFT(b[1],x,1),FFT(b[2],x,1);for(int i=0;i<(1<<x);i++)ans[i]=a[0][i]*b[2][i]+a[2][i]*b[0][i]-Z(2,0)*a[1][i]*b[1][i];FFT(ans,x,-1);for(int i=m+1;i<=n+1;i++)if(!Get(ans[i]))st[++top]=i-m;cout<<top<<'\n';for(int i=1;i<=top;i++)cout<<st[i]<<' ';return 0;
}

转载于:https://www.cnblogs.com/Emiya-wjk/p/10031586.html

【BZOJ4259】残缺的字符串相关推荐

  1. [BZOJ4259]残缺的字符串

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

  2. 洛谷 - P4173 残缺的字符串(多项式匹配字符串-NTT)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串 sss 和一个长度为 mmm 的字符串 ttt,都含有通配符 '*',现在问字符串 ttt 可以匹配字符串 nnn 的哪些位置 题目分析 ...

  3. P4173 残缺的字符串 FFT匹配含有通配符的字符串

    传送门 文章目录 题意: 思路: 题意: 给你两个长度为m,nm,nm,n的串a,ba,ba,b,问你bbb串中每个长度为mmm的连续字串能否与aaa完全匹配,其中含有通配符∗*∗,输出每个位置的开头 ...

  4. P4173 残缺的字符串

    P4173 残缺的字符串 题意: 有A,B两个串,每个串都有通配符,问A为模板串,对于 B 的每一个位置 i,从这个位置开始连续 m 个字符形成的子串是否可能与 A 串完全匹配? 题解: 我们定义两个 ...

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

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

  6. 【BZOJ】4259: 残缺的字符串 FFT

    [题意]给定长度为m的匹配串B和长度为n的模板串A,求B在A中出现多少次.字符串仅由小写字母和通配符" * "组成,其中通配符可以充当任意一个字符.n<=3*10^5. [算 ...

  7. ●Codevs 4158 残缺的字符串

    题链: http://codevs.cn/problem/4158/ 题解: FFT. 定义两个相同长度的字符串s1,s2的距离为 $$dis(s1,s2)=\sum_{i=0}^{len-1}(s1 ...

  8. 洛谷P4173:残缺的字符串(FFT、通配符匹配)

    解析 通配符匹配的经典题. 设单词串为 AAA,文章串为 BBB. 把 AAA 翻转一下,判断问题就能转化为一个卷积的形式: F(p)=&i=0m−1match(Ai+1,Bp−i)F(p)= ...

  9. LGP4173残缺的字符串

    题解 由于有通配符,所以$kmp$失效了: 将通配符看成0,其余字符看成互不相同的数字,$A,B$串对应得到$a,b$数组; 定义: $f(p) = \sum_{i=0}^{m-1} a_{i}b_{ ...

最新文章

  1. 记一次有惊无险的 JVM 优化经历!
  2. “混”的中层们,你们的下一站是?
  3. python 多维数组轴_python – numpy通过任意轴重塑多维数组
  4. SQL Server Error 15404解决方案
  5. 2020-09-09
  6. input html5 新特性,html5 input 新特性
  7. 大数据平台设计哲学的重构
  8. 24. cc.Director与资源加载策略
  9. Windows10从 微软商店 安装 linux(ubuntu)
  10. java 网页转pdf_JAVA中将html转换成pdf
  11. win7下计算机假死,造成Windows7系统假死的原因及处理方法
  12. C语言中ret的作用,c-RET抑制剂 | c-RET Inhibitor
  13. 识别括号或花括号嵌套
  14. 百旺红字发票信息表显示服务器返回为空,红字发票信息表状态详细说明
  15. yolov5s.yaml中各参数作用意义及使用netron工具来可视化yolov5s的结构
  16. 计算机网络机房需要气体灭火吗,哪些场所需要设置气体灭火系统?
  17. Gradle 项目配置阿里云仓库
  18. Python多值函数
  19. # IDEA如何从dao层接口快速调转到xml文件
  20. TI的DRV8841可以被国产电机驱动芯片TMI8263所取代

热门文章

  1. 经典题---数组改“貌”
  2. Sparkamp;Spark性能调优实战
  3. 课程导入导出中的知识点操作
  4. Exchange server 2010系列教程之一 安装Exchange 2010准备条件
  5. 前端开发者必备的Nginx知识
  6. [SpringBoot]全局异常处理
  7. 10个免费好用功能强大的网页动画效果库
  8. Hadoop streaming 排序、分桶参数设置
  9. Quartz的Scheduler初始化源码分析
  10. FineReport中如何自定义登录界面