zoukankan      html  css  js  c++  java
  • 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 << '
    ';
    	return 0;
    }
    
  • 相关阅读:
    423. Reconstruct Original Digits from English
    400. Nth Digit
    397. Integer Replacement
    396. Rotate Function
    365. Water and Jug Problem
    335. Self Crossing
    319. Bulb Switcher
    线段树-hdu2795 Billboard(贴海报)
    线段树---求逆序数
    线段树——单点替换区间最值
  • 原文地址:https://www.cnblogs.com/Isaunoya/p/12639799.html
Copyright © 2011-2022 走看看