bzoj 4259: 残缺的字符串
这题好神啊,居然是fft,表示一直在往数据结构上想。
把'*'当成0,那么两个串可以匹配当且仅当$$\sum (a[i]-b[i])^2\times a[i]\times b[i]==0$$
我们可以把平方拆开,然后就变成了几个乘积相加的形式,那就大力翻转一个串然后跑FFT。
因为最开始MLE了所以复制粘贴了好多东西。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cmath> 6 #define N 1200005 7 #define M 300005 8 #define pi acos(-1) 9 #define E complex 10 using namespace std; 11 struct complex 12 { 13 double x,y; 14 complex(double _x,double _y){x=_x;y=_y;} 15 complex(){;} 16 friend complex operator * (const complex &a,const complex &b) 17 { 18 complex c;c.x=a.x*b.x-a.y*b.y;c.y=a.x*b.y+a.y*b.x;return c; 19 } 20 friend complex operator / (complex a,double b) 21 { 22 return complex(a.x/b,a.y/b); 23 } 24 friend complex operator + (complex a,complex b) 25 { 26 return complex(a.x+b.x,a.y+b.y); 27 } 28 friend complex operator - (complex a,complex b) 29 { 30 return complex(a.x-b.x,a.y-b.y); 31 } 32 }; 33 int R[N];int n; 34 void fft(E *a,int f) 35 { 36 for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]); 37 for(int i=1;i<n;i<<=1) 38 { 39 E wn(cos(pi/i),f*sin(pi/i)); 40 for(int j=0;j<n;j+=(i<<1)) 41 { 42 E w(1,0); 43 for(int k=0;k<i;k++,w=w*wn) 44 { 45 E x=a[j+k],y=w*a[j+k+i]; 46 a[j+k]=x+y;a[j+k+i]=x-y; 47 } 48 } 49 } 50 if(f==-1)for(int i=0;i<n;i++)a[i]=a[i]/n; 51 } 52 int nn,mm; 53 char s1[M],s2[M],s3[M]; 54 E a1[N],b1[N],c1[N]; 55 int ans[N]; 56 int st[M],top; 57 int main() 58 { 59 scanf("%d%d",&nn,&mm); 60 scanf("%s",s3);scanf("%s",s2); 61 int l=0; 62 for(n=1;n<2*mm;n<<=1)l++; 63 for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(l-1)); 64 for(int i=0;i<nn;i++)s1[i]=s3[nn-i-1]; 65 for(int i=0;i<mm;i++) 66 { 67 int tmp=s2[i]-'a'+1;double p=tmp+0.0; 68 if(s2[i]=='*')p=0; 69 b1[i].x=p; 70 } 71 for(int i=0;i<nn;i++) 72 { 73 int tmp=s1[i]-'a'+1;double p=tmp+0.0; 74 if(s1[i]=='*')p=0; 75 a1[i].x=p*p*p; 76 } 77 fft(a1,1);fft(b1,1); 78 for(int i=0;i<n;i++)c1[i]=a1[i]*b1[i]; 79 for(int i=0;i<n;i++)a1[i].x=a1[i].y=b1[i].x=b1[i].y=0; 80 81 for(int i=0;i<mm;i++) 82 { 83 int tmp=s2[i]-'a'+1;double p=tmp+0.0; 84 if(s2[i]=='*')p=0; 85 b1[i].x=p*p; 86 } 87 for(int i=0;i<nn;i++) 88 { 89 int tmp=s1[i]-'a'+1;double p=tmp+0.0; 90 if(s1[i]=='*')p=0; 91 a1[i].x=p*p; 92 } 93 fft(a1,1);fft(b1,1); 94 for(int i=0;i<n;i++)c1[i]=c1[i]-(a1[i]*b1[i]),c1[i]=c1[i]-(a1[i]*b1[i]); 95 for(int i=0;i<n;i++)a1[i].x=a1[i].y=b1[i].x=b1[i].y=0; 96 97 for(int i=0;i<mm;i++) 98 { 99 int tmp=s2[i]-'a'+1;double p=tmp+0.0; 100 if(s2[i]=='*')p=0; 101 b1[i].x=p*p*p; 102 } 103 for(int i=0;i<nn;i++) 104 { 105 int tmp=s1[i]-'a'+1;double p=tmp+0.0; 106 if(s1[i]=='*')p=0; 107 a1[i].x=p; 108 } 109 fft(a1,1);fft(b1,1); 110 for(int i=0;i<n;i++)c1[i]=c1[i]+(a1[i]*b1[i]); 111 112 fft(c1,-1); 113 114 for(int i=nn-1;i<mm;i++) 115 { 116 if(fabs(c1[i].x)<0.5) 117 { 118 st[++top]=i-nn+2; 119 } 120 } 121 printf("%d\n",top); 122 for(int i=1;i<=top;i++) 123 { 124 if(i!=top)printf("%d ",st[i]); 125 else printf("%d\n",st[i]); 126 } 127 return 0; 128 }