BZOJ 4259: 残缺的字符串
Description
有通配符的字符串匹配.\(n,m\leqslant 3\times 10^5\)
Solution
FFT.
跟上题差不多,不过S也有通配符,那么再加一个S进去就行了...
\(D_k=\sum_{i+j=k}(S_i-T_j)^2S_iT_j\)
被卡常了qwq...
Code
/**************************************************************
Problem: 4259
User: BeiYu
Language: C++
Result: Accepted
Time:7640 ms
Memory:67924 kb
****************************************************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1100500;
const double Pi = M_PI;
namespace Pol {
struct cp {
double x,y;
cp(double _x=0,double _y=0) :x(_x),y(_y) {};
};
cp operator + (const cp &a,const cp &b) { return cp(a.x+b.x,a.y+b.y); }
cp operator - (const cp &a,const cp &b) { return cp(a.x-b.x,a.y-b.y); }
cp operator * (const cp &a,const cp &b) { return cp(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x); }
int pn;
int rev[N];
void init(int n) {
for(pn=1;pn<=n;pn<<=1);
for(int i=0,j=0;i<pn;i++) {
rev[i]=j;
for(int k=pn>>1;(j^=k)<k;k>>=1);
}
}
void Rev(cp a[],int n=pn) {
for(int i=0;i<n;i++) if(rev[i]>i) swap(a[i],a[rev[i]]);
}
void DFT(cp a[],int r=1,int n=pn) {
Rev(a);
for(int i=2;i<=n;i<<=1) {
cp wi=cp(cos(2*Pi/i),r*sin(2*Pi/i));
for(int j=0;j<n;j+=i) {
cp w=cp(1,0);
for(int k=j;k<j+i/2;k++) {
cp t1=a[k],t2=w*a[k+i/2];
a[k]=t1+t2,a[k+i/2]=t1-t2;
w=w*wi;
}
}
}if(!~r) for(int i=0;i<n;i++) a[i].x/=n;
}
void FFT(cp a[],cp b[],cp c[],int n=pn) {
DFT(a,1,n),DFT(b,1,n);
for(int i=0;i<n;i++) c[i]=a[i]*b[i];
DFT(c,-1,n);
}
}
using namespace Pol;
int n,m;
char s[N],t[N];
double a[N],b[N];
LL st[N];
cp ss[N],tt[N];
int main() {
scanf("%d%d",&m,&n);
scanf("%s%s",t,s);
n=strlen(s),m=strlen(t);
reverse(t,t+m);
init(n+m);
for(int i=0;i<n;i++) a[i]=s[i]=='*'?0:s[i]-'a'+1;
for(int i=0;i<m;i++) b[i]=t[i]=='*'?0:t[i]-'a'+1;
memset(ss,0,sizeof(ss)),memset(tt,0,sizeof(tt));
for(int i=0;i<pn;i++) ss[i].x=a[i]*a[i]*a[i],tt[i].x=b[i];
FFT(ss,tt,ss);
for(int i=0;i<pn;i++) st[i]+=(LL)(ss[i].x+0.5);
memset(ss,0,sizeof(ss)),memset(tt,0,sizeof(tt));
for(int i=0;i<pn;i++) ss[i].x=a[i]*a[i],tt[i].x=b[i]*b[i];
FFT(ss,tt,ss);
for(int i=0;i<pn;i++) st[i]-=2*(LL)(ss[i].x+0.5);
memset(ss,0,sizeof(ss)),memset(tt,0,sizeof(tt));
for(int i=0;i<pn;i++) ss[i].x=a[i],tt[i].x=b[i]*b[i]*b[i];
FFT(ss,tt,ss);
for(int i=0;i<pn;i++) st[i]+=(LL)(ss[i].x+0.5);
int ans=0;
for(int i=m-1;i<n;i++) if(st[i]==0) ans++;
printf("%d\n",ans);
for(int i=m-1;i<n;i++) if(st[i]==0) printf("%d ",i-m+1+1);
return 0;
}

浙公网安备 33010602011771号