CF528D Fuzzy Search [FFT]
没啥好说的…
#include <bits/stdc++.h>
using namespace std;
#define int long long
struct cpx {
double x, y;
cpx(double _x = 0, double _y = 0) {
x = _x;
y = _y;
}
};
cpx operator * (cpx x , cpx y) {
return cpx(x.x * y.x - x.y * y.y, x.x * y.y + x.y * y.x);
}
cpx operator + (cpx x , cpx y) {
return cpx(x.x + y.x , x.y + y.y);
}
cpx operator - (cpx x , cpx y) {
return cpx(x.x - y.x , x.y - y.y);
}
const int maxn = 6e5 + 56;
const double pi = acos(-1);
int rev[maxn];
int limit;
void fft(cpx *a, int type) {
for(int i = 0 ; i < limit ; i ++)
if(i < rev[i])
swap(a[i], a[rev[i]]);
for(int len = 1 ; len < limit ; len <<= 1) {
cpx Wn = cpx(cos(pi / len), sin(pi / len) * type);
for(int i = 0 ; i < limit ; i += len << 1) {
cpx w = cpx(1 , 0);
for(int j = 0 ; j < len ; j ++) {
cpx X = a[i + j];
cpx Y = a[i + j + len] * w;
a[i + j] = X + Y;
a[i + j + len] = X - Y;
w = w * Wn;
}
}
}
}
int n , m , k;
char s[maxn], t[maxn];
cpx a[maxn], b[maxn];
int cnt[maxn];
void qwq(char c) {
for(int i = 0 ; i < limit ; i ++)
a[i] = cpx(0 , 0);
for(int i = 0 ; i < limit ; i ++)
b[i] = cpx(0 , 0);
int las = -1e9;
for(int i = 0 ; i < n ; i ++) {
if(s[i] == c) las = i;
if(i - las <= k)
a[i] = cpx(1 , 0);
}
las = 1e9;
for(int i = n - 1 ; ~ i ; i --) {
if(s[i] == c) las = i;
if(las - i <= k)
a[i] = cpx(1 , 0);
}
for(int i = 0 ; i < m ; i ++) {
if(t[i] == c)
b[i] = cpx(1 , 0);
}
fft(a , 1);
fft(b , 1);
for(int i = 0 ; i < limit ; i ++)
a[i] = a[i] * b[i];
fft(a , -1);
for(int i = 0 ; i < n ; i ++)
cnt[i] += (int)(a[i].x / limit + 0.5);
}
signed main() {
ios :: sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> n >> m >> k;
cin >> s >> t;
reverse(t, t + m);
limit = 1;
int l = 0;
while(limit <= n + m)
limit <<= 1, ++ l;
for(int i = 1 ; i <= limit ; i ++)
rev[i] = rev[i >> 1] >> 1 | (i & 1) << l - 1;
qwq('A');
qwq('G');
qwq('C');
qwq('T');
int ans = 0;
for(int i = 0 ; i < n ; i ++)
if(cnt[i] == m)
++ ans;
cout << ans << '\n';
return 0;
}