传送门

话说为什么字符串会和卷积扯上关系呢……到底得脑洞大到什么程度才能想到这种东西啊……大佬太珂怕了……

因为通配符的关系,自动机已经废了

那么换种方式考虑,如果两个字符串每一位对应的编码都相等,那么这两个字符串相等

编码相等就代表$\sum_{i=1}^na[i]-b[i]=0$

然而这是不对的,有可能前面少一点,后面多一点,最好加起来还是$0$

那就平方一下$\sum_{i=1}^n(a[i]-b[i]=0)^2=0$,那就大丈夫了

于是我们得到了比一位一位匹配更麻烦的方法

看到平方……把它展开一下试试……结果……$\sum_{i=1}^na[i]^2+b[i]^2-2a[i]b[i]$

我们考虑把$b$给倒过来……这就是三个卷积啊!直接用FFT啊!加起来之后如果为$0$说明匹配上了

然而……通配符怎么办……如果有一位有通配符,那么这一位代表的编码相减肯定是$0$了

那么再改一下$\sum_{i=1}^na[i]*b[i]*(a[i]-b[i])=0$,如果一个位置是通配符,就把$a[i]/b[i]$设为$0$

然后就没有问题了……求一下卷积……如果第$i$位为$0$那么它就是一个能匹配上的字符串的结尾

 //minamoto
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int N=;const double Pi=acos(-1.0);
struct complex{
double x,y;
complex(double xx=,double yy=){x=xx,y=yy;}
complex operator +(complex b){return complex(x+b.x,y+b.y);}
complex operator -(complex b){return complex(x-b.x,y-b.y);}
complex operator *(complex b){return complex(x*b.x-y*b.y,x*b.y+y*b.x);}
}A[N],B[N],C[N];
int n,m,l,r[N],limit=;double a[N],b[N];
void FFT(complex *A,int type){
for(int i=;i<limit;++i)
if(i<r[i]) swap(A[i],A[r[i]]);
for(int mid=;mid<limit;mid<<=){
complex Wn(cos(Pi/mid),type*sin(Pi/mid));
for(int R=mid<<,j=;j<limit;j+=R){
complex w(,);
for(int k=;k<mid;++k,w=w*Wn){
complex x=A[j+k],y=w*A[j+mid+k];
A[j+k]=x+y,A[j+mid+k]=x-y;
}
}
}
if(type==-)
for(int i=;i<limit;++i) A[i]=(int)(A[i].x/limit+0.5);
}
char s1[],s2[];int l1,l2,ans[N],res=;
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d",&l2,&l1);
scanf("%s%s",s2,s1);
m=l1+l2;
while(limit<=m) limit<<=,++l;
for(int i=;i<limit;++i)
r[i]=(r[i>>]>>)|((i&)<<(l-));
for(int i=;i<l1;++i)
a[i]=s1[i]=='*'?:s1[i]-'a'+;
for(int i=;i<l2;++i)
b[l2-i-]=s2[i]=='*'?:s2[i]-'a'+;
for(int i=;i<l1;++i) A[i].x=a[i]*a[i]*a[i];
for(int i=;i<l2;++i) B[i].x=b[i];
FFT(A,),FFT(B,);
for(int i=;i<limit;++i) C[i]=A[i]*B[i];//a^3*b
for(int i=;i<limit;++i) A[i].x=a[i]*a[i],A[i].y=;
for(int i=;i<limit;++i) B[i].x=b[i]*b[i],B[i].y=;
FFT(A,),FFT(B,);
complex tmp(,);
for(int i=;i<limit;++i) C[i]=C[i]-A[i]*B[i]*tmp;//-2ab*a*b
for(int i=;i<limit;++i) A[i].x=a[i],A[i].y=;
for(int i=;i<limit;++i) B[i].x=b[i]*b[i]*b[i],B[i].y=;
FFT(A,),FFT(B,);
for(int i=;i<limit;++i) C[i]=C[i]+A[i]*B[i];//b^3*a
FFT(C,-);
for(int i=l2-;i<l1;++i)
if(C[i].x==0.0) ans[++res]=i-l2+;
printf("%d\n",res);
for(int i=;i<=res;++i) printf("%d ",ans[i]);
return ;
}

洛谷P4173 残缺的字符串(FFT)的更多相关文章

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

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

  2. 洛谷 P4173 残缺的字符串

    (不知道xjb KMP可不可以做的说) (假设下标都以0开头) 对于有一定偏移量的序列的 对应位置 匹配或者数值计算的题,这里是有一种套路的,就是把其中一个序列翻转过来,然后卷积一下,所得到的新序列C ...

  3. 洛谷P4173 残缺的字符串

    题目大意: 两个带通配符的字符串\(a,b\),求\(a\)在\(b\)中出现的位置 字符串长度\(\le 300000\) 考虑魔改一发\(kmp\),发现魔改不出来 于是考虑上网搜题解 然后考虑\ ...

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

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

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

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

  6. P4173 残缺的字符串 fft

    题意:给你两个字符串,问你第一个在第二个中出现过多少次,并输出位置,匹配时是模糊匹配*可和任意一个字符匹配 题解:fft加速字符串匹配; 假设上面的串是s,s长度为m,下面的串是p,p长度为n,先考虑 ...

  7. luoguP4173 残缺的字符串 FFT

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

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

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

  9. 洛谷.3803.[模板]多项式乘法(FFT)

    题目链接:洛谷.LOJ. FFT相关:快速傅里叶变换(FFT)详解.FFT总结.从多项式乘法到快速傅里叶变换. 5.4 又看了一遍,这个也不错. 2019.3.7 叕看了一遍,推荐这个. #inclu ...

随机推荐

  1. volatile语义

    volatile在Java内存模型(JMM)中,保证共享变量对所有线程可见,但不保证原子性.volatile语义是同步,通过共享变量的方式,完成线程间的通信. 为什么需要volatile Java内存 ...

  2. Compare and Swap(CAS)

    CAS(Compare and Swap)是个原子操作.拿到一个新值后,CAS将其与内存中的值进行比较,若内存中的值和这个值不一样,则将这个值写入内存,否则,不做操作.在Java的 java.util ...

  3. DDD学习笔录——领域驱动设计DDD概念总结

  4. 问题:C#将base64转换成二进制图片;结果:c# Base64编码和图片的互相转换代码

    c# Base64编码和图片的互相转换代码 Base64编码在Web方面有很多应用,譬如在URL.电子邮件方面.网上有很多相关的资源用于提供Base64编码和其他编码的转换,.Net Framewor ...

  5. AudioFormat

    AudioFormat   用于访问 一系列语音格式和通道配置常量 例如用于AudioTrack 和AudioRecord中 The AudioFormat class is used to acce ...

  6. centos 安装 python flask 和python3安装flask

    pip install Flask python3安装 pip3 install flask

  7. Mysql GROUP_CONCAT 使用注意事项

    GROUP_CONCAT 函数返回一个字符串结果,该结果由分组中的值连接组合而成,常和 GROUP BY 连用. 如果需要自定义分隔符可以使用 SEPARATOR. 示例: SELECT GROUP_ ...

  8. Ubuntu,kubuntu与xubuntu的差别 Ubuntu各版本主要差异

    Ubuntu各版本主要差异 Ubuntu官方考虑到使用者的不同需求,提供各种不同的发行版.虽然发布了几种版本的Ubuntu系统,但是它们的核心系统是一模一样的.可以这么说不同发行版的Ubuntu的区别 ...

  9. 算法Sedgewick第四版-第1章基础-1.4 Analysis of Algorithms-004计算内存

    1. 2. 3.字符串

  10. Windows Live Writer 使用指南

    一.简介 Windows Live Writer 是一个强大的离线博客编辑工具,通过它可以离线编辑内容丰富的博文,除了自身强大的编辑功能之外,还提供了接口,让其它开发人员通过插件提供工具自身没有提供的 ...