ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

「题解」Codeforces 528D Fuzzy Search

2021-09-24 19:00:41  阅读:134  来源: 互联网

标签:Search return int 题解 值为 Codeforces cpx ld include


分别仅考虑 \(A,C,G,T\),把匹配成功的位置取个交集就可以。

使用 FFT 来完成字符串匹配。

现在仅考虑 \(A\),把 \(S\) 中不会和 \(A\) 匹配上的位置上的字符设为 \(o\),把 \(T\) 中不是 \(A\) 的字符设为 \(\#\),则匹配函数 \(C(x,y)\) (其中 \(x\) 来自 \(S\),\(y\) 来自 \(T\))要满足:

  • \(=0,x=A,y=A\);
  • \(=0,x=A,y=\#\);
  • \(>0,x=o,y=A\);
  • \(=0,x=o,y=\#\).

这样的 \(C\) 才能满足匹配成功值为 \(0\),否则大于 \(0\).

设:

  • \(S\) 中的 \(A\) 值为 \(0\),\(o\) 值为 \(1\);

  • \(T\) 中的 \(A\) 值为 \(1\),\(\#\) 值为 \(0\);

  • \(C(x,y)=xy\).

对于每个字符只需要一次 FFT 就可以了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
typedef long long ll;
typedef double ld;
inline int Max(int x, int y) { return x > y ? x : y; }
inline int Min(int x, int y) { return x < y ? x : y; }
const int N = 800010;
const ld pi = acos(-1.0);
struct cpx {
	ld x, y;
	cpx(ld xx = 0, ld yy = 0) { x = xx; y = yy; }
};
cpx operator + (cpx a, cpx b) { return cpx(a.x + b.x, a.y + b.y); }
cpx operator - (cpx a, cpx b) { return cpx(a.x - b.x, a.y - b.y); }
cpx operator * (cpx a, cpx b) { return cpx(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); }
cpx *getw(int n, int type) {
	static cpx w[N/2];
	w[0] = cpx(1, 0); w[1] = cpx(cos(2 * pi / n), sin(2 * pi / n) * type);
	for(int i = 2; i < n/2; ++i) w[i] = w[i-1] * w[1];
	return w;
}
int p[N];
void FFT(cpx *a, int n, int type) {
	for(int i = 0; i < n; ++i) if(i < p[i]) std::swap(a[i], a[p[i]]);
	for(int i = 1; i < n; i <<= 1) {
		cpx *w = getw(i << 1, type);
		for(int j = 0; j < n; j += i << 1) {
			cpx *b = a + j, *c = b + i;
			for(int k = 0; k < i; ++k) {
				cpx v = w[k] * c[k];
				c[k] = b[k] - v;
				b[k] = b[k] + v;
			}
		}
	}
	if(type == -1) for(int i = 0; i < n; ++i) a[i].x /= n;
}
void mul(int *a, int *b, int *c, int n, int m) {
	static cpx f[N], g[N];
	int len = 1, ct = 0;
	while(len <= n + m) len <<= 1, ++ct;
	for(int i = 0; i < len; ++i) p[i] = (p[i>>1]>>1) | ((i&1) << (ct-1));
	for(int i = 0; i < len; ++i) f[i] = g[i] = cpx(0, 0);
	for(int i = 0; i < n; ++i) f[i] = cpx(a[i], 0);
	for(int i = 0; i < m; ++i) g[i] = cpx(b[i], 0);
	FFT(f, len, 1);
	FFT(g, len, 1);
	for(int i = 0; i < len; ++i) f[i] = f[i] * g[i];
	FFT(f, len, -1);
	for(int i = 0; i < len; ++i) c[i] = (int)(f[i].x+0.5);
}
int n, m, k;
int id[300], c[4][N], A[4][N];
char s[N], t[N];
int f[N], g[N];
signed main() {
	scanf("%d%d%d", &n, &m, &k);
	id['A'] = 0, id['G'] = 1, id['C'] = 2, id['T'] = 3;
	scanf("%s", s); scanf("%s", t);
	for(int i = 0; i < n; ++i) {
		s[i] = id[(int)s[i]]; t[i] = id[(int)t[i]];
		++c[(int)s[i]][Max(i-k, 0)];
		--c[(int)s[i]][Min(i+k+1, n)];
	}
	for(int i = 1; i < n; ++i) for(int j = 0; j < 4; ++j) c[j][i] += c[j][i-1];
	for(int o = 0; o < 4; ++o) {
		for(int i = 0; i < n; ++i)
			f[i] = c[o][i] ? 0 : 1;
		for(int i = 0; i < m; ++i)
			g[i] = t[i] == o ? 1 : 0;
		std::reverse(g, g + m);
		mul(f, g, A[o], n, m);
	}
	int ans = 0;
	for(int i = m-1; i < n; ++i)
		if(!A[0][i] && !A[1][i] && !A[2][i] && !A[3][i])
			++ans;
	printf("%d\n", ans);
	return 0;
}

标签:Search,return,int,题解,值为,Codeforces,cpx,ld,include
来源: https://www.cnblogs.com/do-while-true/p/15331799.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有