# bzoj 4259: 残缺的字符串

 1 #include <cstdio>
2 #include <iostream>
3 #include <cmath>
4 #include <cstring>
5 #define pi acos(-1)
6 using namespace std;
7
8 const int maxn=600005;
9
10 struct complex
11 {
12     double r,i;
13     complex (double a=0, double b=0) {r=a; i=b;}
14     complex operator + (const complex a) {return complex(r+a.r,i+a.i);}
15     complex operator - (const complex a) {return complex(r-a.r,i-a.i);}
16     complex operator * (const complex a) {return complex(r*a.r-i*a.i,r*a.i+i*a.r);}
17 }A[maxn<<1],B[maxn<<1],ans[maxn<<1];
18
19 int N,n,m,cnt,Ans[maxn],a[maxn],b[maxn],rev[maxn];
20 char s[maxn],t[maxn];
21
22 void FFT(complex *a, int f)
23 {
24     for (int i=0; i<N; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
25     for (int h=2; h<=N; h<<=1)
26     {
27         complex wn(cos(2*pi*f/h),sin(2*pi*f/h));
28         for (int i=0; i<N; i+=h)
29         {
30             complex w(1,0);
31             for (int j=0; j<(h>>1); j++,w=w*wn)
32             {
33                 complex x=a[i+j],y=w*a[i+j+(h>>1)];
34                 a[i+j]=x+y;
35                 a[i+j+(h>>1)]=x-y;
36             }
37         }
38     }
39     if (f==-1) for (int i=0; i<N; i++) a[i].r/=(double)N;
40 }
41
42 int main(int argc, char const *argv[])
43 {
44     scanf("%d%d",&m,&n);
45     scanf("%s",s); scanf("%s",t);
46     for (int i=0; i<m; i++) a[i]=(s[m-i-1]=='*')?0:s[m-i-1]-'a'+1;
47     for (int i=0; i<n; i++) b[i]=(t[i]=='*')?0:t[i]-'a'+1;
48     int L=0;
49     for (N=1; N<(n+m); N<<=1) L++;
50     for (int i=0; i<N; i++)    rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
51
52     for (int i=0; i<m; i++) A[i]=a[i]*a[i]*a[i];
53     for (int i=0; i<n; i++) B[i]=b[i];
54     FFT(A,1); FFT(B,1);
55     for (int i=0; i<N; i++) ans[i]=A[i]*B[i];
56
57     memset(A,0,sizeof(A)); memset(B,0,sizeof(B));
58     for (int i=0; i<m; i++) A[i]=a[i];
59     for (int i=0; i<n; i++) B[i]=b[i]*b[i]*b[i];
60     FFT(A,1); FFT(B,1);
61     for (int i=0; i<N; i++) ans[i]=ans[i]+A[i]*B[i];
62
63     memset(A,0,sizeof(A)); memset(B,0,sizeof(B));
64     for (int i=0; i<m; i++) A[i]=2*a[i]*a[i];
65     for (int i=0; i<n; i++) B[i]=b[i]*b[i];
66     FFT(A,1); FFT(B,1);
67     for (int i=0; i<N; i++) ans[i]=ans[i]-A[i]*B[i];
68
69     FFT(ans,-1);
70     for (int i=m-1; i<n; i++) if (ans[i].r<0.1 && ans[i].r>-0.1) Ans[++cnt]=i-m+2;
71     printf("%d\n",cnt);
72     for (int i=1; i<=cnt; i++) printf("%d ",Ans[i]);
73     return 0;
74 }

posted @ 2017-04-19 15:34  ws_ccd  阅读(306)  评论(0编辑  收藏  举报