orz xuruifan发discuss问题解……
题解可以看这题discuss
至于如何用FFT算卷积,我们写一下高精乘,用字母代表每一位,发现乘完了其实就是卷积的形式
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<iomanip> #include<cstring> #include<cmath> #include<ctime> #include<vector> #include<stack> #include<queue> #include<set> #include<bitset> #include<map> using namespace std; #define MAXN 400010 #define MAXM 10010 #define INF 1000000000 #define MOD 1000000007 #define ll long long #define eps 1e-8 const double pai=acos(-1); struct cl{ double x; double y; cl(){ } cl(double _x,double _y){ x=_x; y=_y; } cl operator =(double x){ this->x=x; this->y=0; return *this; } friend cl operator +(cl x,cl y){ return cl(x.x+y.x,x.y+y.y); } friend cl operator -(cl x,cl y){ return cl(x.x-y.x,x.y-y.y); } friend cl operator /(cl x,double y){ return cl(x.x/y,x.y/y); } friend cl operator *(cl x,double y){ return cl(x.x*y,x.y*y); } friend cl operator *(cl x,cl y){ return cl(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x); } }; char S[MAXN],T[MAXN]; int s[MAXN],t[MAXN]; cl a1[MAXN],a2[MAXN],a3[MAXN],b1[MAXN],b2[MAXN],b3[MAXN],a[MAXN],b[MAXN],ans[MAXN]; int n,m; int L; int R[MAXN]; int ANS; void fft(cl *x,int y){ int i,j,k; for(i=0;i<n;i++){ if(i<R[i]){ swap(x[i],x[R[i]]); } } for(i=1;i<n;i<<=1){ cl wn(cos(pai/i),y*sin(pai/i)); for(j=0;j<n;j+=(i<<1)){ cl w(1,0); for(k=0;k<i;k++,w=w*wn){ cl X=x[j+k],Y=w*x[j+k+i]; x[j+k]=X+Y; x[j+k+i]=X-Y; } } } if(y==-1){ for(i=0;i<n;i++){ x[i].x/=n; x[i].y/=n; } } } void FFT(cl *a,cl *b,int f){ int i; fft(a,1); fft(b,1); for(i=0;i<n;i++){ a[i]=a[i]*b[i]; } fft(a,-1); for(i=0;i<n;i++){ ans[i]=ans[i]+(a[i]*f); } } int main(){ int i; scanf("%s%s",S,T); n=strlen(S); m=strlen(T); for(i=1;i<=m/2;i++){ swap(T[i-1],T[m-i]); } for(i=0;i<n;i++){ s[i]=S[i]; t[i]=T[i]; if(T[i]=='?'){ t[i]=0; } a1[i]=s[i]*s[i]*s[i]; b1[i]=t[i]; a2[i]=s[i]*s[i]; b2[i]=t[i]*t[i]; a3[i]=s[i]; b3[i]=t[i]*t[i]*t[i]; } int N=n*2; for(n=1;n<=N;n<<=1){ L++; } for(i=0;i<n;i++){ R[i]=(R[i>>1]>>1|((i&1)<<(L-1))); } FFT(a1,b1,1); FFT(a2,b2,-2); FFT(a3,b3,1); for(i=m-1;i<N/2;i++){ if(int(ans[i].x+0.1)==0){ ANS++; } } printf("%d\n",ANS); for(i=m-1;i<N/2;i++){ if(int(ans[i].x+0.1)==0){ printf("%d\n",i-(m-1)); } } return 0; } /* */