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;
}
posted @ 2020-04-05 23:05  _Isaunoya  阅读(137)  评论(0编辑  收藏  举报