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; }