BZOJ4503 两个串

来源:互联网 发布:js url encode php 编辑:程序博客网 时间:2024/06/18 13:04

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-8const 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;}/**/


0 0
原创粉丝点击