# @bzoj - 4259@ 残缺的字符串

## @accepted code@

#include <cmath>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

#define double long double

const int MAXN = 300000*4;
const double PI = acos(-1);
const double EPS = 0.5;

struct complex{
double r, i; complex() {}
complex(double _r, double _i) : r(_r), i(_i) {}
friend complex operator + (complex A, complex B) {
return complex(A.r + B.r, A.i + B.i);
}
friend complex operator - (complex A, complex B) {
return complex(A.r - B.r, A.i - B.i);
}
friend complex operator * (complex A, complex B) {
return complex(A.r*B.r - A.i*B.i, A.i*B.r + B.i*A.r);
}
friend complex operator / (complex A, double k) {
return complex(A.r / k, A.i / k);
}
};

void fft(complex *A, int n, int type) {
for(int i=0,j=0;i<n;i++) {
if( i < j ) swap(A[i], A[j]);
for(int k=(n>>1);(j^=k)<k;k>>=1);
}
for(int s=2;s<=n;s<<=1) {
int t = (s >> 1);
complex u = complex(cos(type*2*PI/s), sin(type*2*PI/s));
for(int j=0;j<n;j+=s) {
complex p = complex(1, 0);
for(int k=0;k<t;k++,p=p*u) {
complex x = A[j+k], y = A[j+k+t]*p;
A[j+k] = x + y, A[j+k+t] = x - y;
}
}
}
if( type == -1 ) {
for(int i=0;i<n;i++)
A[i] = A[i] / n;
}
}
int length(int n) {
int len; for(len = 1; len < n; len <<= 1);
return len;
}

double A[MAXN + 5], B[MAXN + 5];
complex f[MAXN + 5], g[MAXN + 5], h[MAXN + 5];

char sa[MAXN + 5], sb[MAXN + 5];

vector<int>ans;

int main() {
int m, n; scanf("%d%d", &m, &n);
scanf("%s%s", sa, sb);
for(int i=0;i<m;i++) A[m-1-i] = (sa[i] == '*' ? 0 : sa[i] - 'a' + 1);
for(int i=0;i<n;i++) B[i] = (sb[i] == '*' ? 0 : sb[i] - 'a' + 1);
int len = length(n + m - 1);

for(int i=0;i<len;i++) f[i] = g[i] = complex(0, 0);
for(int i=0;i<m;i++) f[i].r = A[i]*A[i]*A[i];
for(int i=0;i<n;i++) g[i].r = B[i];
fft(f, len, 1), fft(g, len, 1);
for(int i=0;i<len;i++) h[i] = h[i] + f[i]*g[i];

for(int i=0;i<len;i++) f[i] = g[i] = complex(0, 0);
for(int i=0;i<m;i++) f[i].r = A[i]*A[i];
for(int i=0;i<n;i++) g[i].r = B[i]*B[i];
fft(f, len, 1), fft(g, len, 1);
for(int i=0;i<len;i++) h[i] = h[i] - f[i]*g[i] - f[i]*g[i];

for(int i=0;i<len;i++) f[i] = g[i] = complex(0, 0);
for(int i=0;i<m;i++) f[i].r = A[i];
for(int i=0;i<n;i++) g[i].r = B[i]*B[i]*B[i];
fft(f, len, 1), fft(g, len, 1);
for(int i=0;i<len;i++) h[i] = h[i] + f[i]*g[i];

fft(h, len, -1);
for(int i=m-1;i<n;i++) {
//		printf("%d : %.6f %.6f\n", i, h[i].r, h[i].i);
if( fabs(h[i].r) < EPS ) ans.push_back(i-m+2);
}
printf("%d\n", (int)ans.size());
for(int i=0;i<ans.size();i++)
printf("%d%c", ans[i], i + 1 == ans.size() ? '\n' : ' ');
}


## @details@

fft 一大缺点就是精度损失比较大，eps 太小就会误判。。。

posted @ 2020-01-20 19:54  Tiw_Air_OAO  阅读(75)  评论(0编辑  收藏