P4173 殘缺的字符串(FFT)
阿新 • • 發佈:2019-03-10
problem ons cout har tchar pri amp show struct
[Luogu4173]
題解
\(1.\)定義匹配函數
\(2.\)定義完全匹配函數
\(3.\)快速計算每一位的完全匹配函數值
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #define debug(...) fprintf(stderr,__VA_ARGS__) #define Debug(x) cout<<#x<<"="<<x<<endl using namespace std; typedef long long LL; const int INF=1e9+7; inline LL read(){ register LL x=0,f=1;register char c=getchar(); while(c<48||c>57){if(c=='-')f=-1;c=getchar();} while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar(); return f*x; } inline char readc(){ register char c=getchar(); while(c==' '||c=='\n'||c=='\t') c=getchar(); return c; } const int MAXN=2e6+5; const double Pi=acos(-1); struct cmpx{ double x,y; inline cmpx(){} inline cmpx(double _x,double _y){x=_x,y=_y;} inline friend cmpx operator + (cmpx a,cmpx b){return cmpx(a.x+b.x,a.y+b.y);} inline friend cmpx operator - (cmpx a,cmpx b){return cmpx(a.x-b.x,a.y-b.y);} inline friend cmpx operator * (cmpx a,cmpx b){return cmpx(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);} inline friend cmpx operator * (cmpx a,double b){return cmpx(a.x*b,a.y*b);} }A[MAXN],B[MAXN],C[MAXN]; char s[MAXN],t[MAXN]; int ans[MAXN],a[MAXN],b[MAXN]; int n,m; namespace F_F_T{ int rev[MAXN],limit,l; inline void init(int n){ for(limit=1,l=0;limit<=n;limit<<=1) l++; for(int i=0;i<limit;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1)); } inline void FFT(cmpx *A,int type){ for(int i=0;i<limit;i++) if(i<rev[i]) swap(A[i],A[rev[i]]); for(int len=1;len<limit;len<<=1){ cmpx Wn=(cmpx){cos(Pi/len),type*sin(Pi/len)}; for(int i=0;i<limit;i+=(len<<1)){ cmpx w=(cmpx){1,0}; for(int j=0;j<len;j++,w=w*Wn){ cmpx x=A[i+j],y=w*A[i+len+j]; A[i+j]=x+y; A[i+len+j]=x-y; } } } if(type==-1){ for(int i=0;i<limit;i++) A[i].x/=limit; } } }using namespace F_F_T; int main(){ n=read(),m=read(); init(n+m-2); for(int i=n-1;i>=0;i--){ char c=readc(); a[i]=(c!='*')?c-'a'+1:0; } for(int i=0;i<m;i++){ char c=readc(); b[i]=(c!='*')?c-'a'+1:0; } for(int i=0;i<n;i++) A[i]=cmpx(a[i]*a[i]*a[i],0); for(int i=0;i<m;i++) B[i]=cmpx(b[i],0); FFT(A,1);FFT(B,1); for(int i=0;i<limit;i++) C[i]=A[i]*B[i]; for(int i=0;i<limit;i++) A[i]=B[i]=cmpx(0,0); for(int i=0;i<n;i++) A[i]=cmpx(a[i],0); for(int i=0;i<m;i++) B[i]=cmpx(b[i]*b[i]*b[i],0); FFT(A,1);FFT(B,1); for(int i=0;i<limit;i++) C[i]=C[i]+A[i]*B[i]; for(int i=0;i<limit;i++) A[i]=B[i]=cmpx(0,0); for(int i=0;i<n;i++) A[i]=cmpx(a[i]*a[i],0); for(int i=0;i<m;i++) B[i]=cmpx(b[i]*b[i],0); FFT(A,1);FFT(B,1); for(int i=0;i<limit;i++) C[i]=C[i]-A[i]*B[i]*2.0; FFT(C,-1); for(int i=n-1;i<m;i++){ if(fabs(C[i].x)<0.5) ans[++ans[0]]=i-n+2; //printf("%.3lf\n",C[i].x); } printf("%d\n",ans[0]); for(int i=1;i<=ans[0];i++) printf("%d ",ans[i]); }
P4173 殘缺的字符串(FFT)