CF528D. Fuzzy Search [FFT]
CF528D. Fuzzy Search
题意:DNA序列,在母串s中匹配模式串t,对于s中每个位置i,只要s[i-k]到s[i+k]中有c就认为匹配了c。求有多少个位置匹配了t
预处理\(f[i][j]\)表示位置i可以匹配字符j
分别考虑每一个字符c,对s的每个位置i求出用\(s[i,i+m-1]\)匹配t,这个字符匹配了几次
用\(a_i=[s的位置i匹配c],\ b_i=[t_i=c]\)
那么c的匹配次数就是\(c_j=\sum\limits_{i=0}^{m-1}a_{j+i}b_i\),位置i匹配了t当且仅当四种字符的匹配次数和等于t的长度m
~~这时候就可以考虑bitset暴力过了~~
一个常用技巧是,反转模式串(或母串),然后就成了卷积的形式:
\]
这样计算是没有问题的,因为b只有\([0,m-1]\)有值其他地方为0
注意处理每个字符前memset a和b!!!!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=(1<<20)+5, INF=1e9;
const double PI=acos(-1);
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct meow{
double x, y;
meow(double a=0, double b=0):x(a), y(b){}
};
meow operator +(meow a, meow b) {return meow(a.x+b.x, a.y+b.y);}
meow operator -(meow a, meow b) {return meow(a.x-b.x, a.y-b.y);}
meow operator *(meow a, meow b) {return meow(a.x*b.x-a.y*b.y, a.x*b.y+a.y*b.x);}
meow conj(meow a) {return meow(a.x, -a.y);}
typedef meow cd;
namespace FFT{
int n, rev[N];
void ini(int lim) {
n=1; int k=0;
while(n<lim) n<<=1, k++;
for(int i=0; i<n; i++) rev[i] = (rev[i>>1]>>1) | ((i&1)<<(k-1));
}
void dft(cd *a, int flag) {
for(int i=0; i<n; i++) if(i<rev[i]) swap(a[i], a[rev[i]]);
for(int l=2; l<=n; l<<=1) {
int m=l>>1;
cd wn = meow(cos(2*PI/l), flag*sin(2*PI/l));
for(cd *p=a; p!=a+n; p+=l) {
cd w(1, 0);
for(int k=0; k<m; k++) {
cd t = w*p[k+m];
p[k+m] = p[k] - t;
p[k] = p[k] + t;
w=w*wn;
}
}
}
if(flag==-1) for(int i=0; i<n; i++) a[i].x/=n;
}
void mul(cd *a, cd *b) {
dft(a, 1); dft(b, 1);
for(int i=0; i<n; i++) a[i]=a[i]*b[i];
dft(a, -1);
}
}using FFT::mul; using FFT::ini;
int n, m, k, lim, f[N][5], cnt[5], id[300];
cd a[N], b[N], c[N];
char s[N], t[N];
int ans[N];
void solve(int now) {
memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b));
for(int i=0; i<n; i++) a[i].x = f[i][now];
for(int i=0; i<m; i++) b[m-1-i].x = id[(int)t[i]]==now;
mul(a, b);
for(int i=0; i<n; i++) ans[i] += int(a[m-1+i].x+0.5);
}
int main() {
freopen("in","r",stdin);
n=read(); m=read(); k=read();
lim=n+m-1; ini(lim);
scanf("%s%s",s,t);
id['A']=0; id['T']=1; id['C']=2; id['G']=3;
int l=0, r=0; cnt[ id[(int)s[0]] ]++;
for(int i=0; i<n; i++) {
while(l<i-k) cnt[ id[(int)s[l++]] ]--;
while(r<n-1 && r<i+k) cnt[ id[(int)s[++r]] ]++;
for(int j=0; j<4; j++) if(cnt[j]) f[i][j]=1;
}
for(int i=0; i<4; i++) solve(i);
int sum=0;
for(int i=0; i<n; i++) if(ans[i]==m) sum++;
printf("%d",sum);
}
CF528D. Fuzzy Search [FFT]的更多相关文章
- CF-528D Fuzzy Search(FFT字符串匹配)
Fuzzy Search 题意: 给定一个模式串和目标串按下图方式匹配,错开位置不多于k 解题思路: 总共只有\(A C G T\)四个字符,那么我们可以按照各个字符进行匹配,比如按照\(A\)进行匹 ...
- 【Codeforces528D】Fuzzy Search FFT
D. Fuzzy Search time limit per test:3 seconds memory limit per test:256 megabytes input:standard inp ...
- CF528D Fuzzy Search 和 BZOJ4259 残缺的字符串
Fuzzy Search 给你文本串 S 和模式串 T,求 S 的每个位置是否能模糊匹配上 T. 这里的模糊匹配指的是把 T 放到 S 相应位置上之后,T 中每个字符所在位置附近 k 个之内的位置上的 ...
- CF528D Fuzzy Search 字符串匹配+FFT
题意: DNA序列,在母串s中匹配模式串t,对于s中每个位置i,只要s[i-k]到s[i+k]中有c就认为匹配了c.求有多少个位置匹配了t. 分析: 这个字符串匹配的方式,什么kmp,各种自动机都不灵 ...
- CF528D Fuzzy Search (生成函数+FFT)
题目传送门 题目大意:给你两个只包含A,G,C,T的字符串$S$,$T$,$S$长$T$短,按照如下图方式匹配 解释不明白直接上图 能容错的距离不超过$K$,求能$T$被匹配上的次数 $S$串同一个位 ...
- CF528D Fuzzy Search
题意:给定k,只含有ACGT的字符串S和T,求T在S中出现了多少次. 字符匹配:如果S的[i - k, i + k]中有字符x,那么第i位可以匹配x. 解: 首先预处理:f[i][j]表示S的第i位能 ...
- CF528D Fuzzy Search 【NTT】
题目链接 CF528D 题解 可以预处理出\(S\)每个位置能匹配哪些字符 对每种字符 构造两个序列 如果\(S[i]\)可以匹配该字符,则该位置为\(0\),否则为\(1\) 如果\(T[i]\)可 ...
- Codeforces.528D.Fuzzy Search(FFT)
题目链接 \(Descripiton\) 给出文本串S和模式串T和k,S,T为DNA序列(只含\(A,T,G,C\)).对于S中的每个位置\(i\),只要\(s[i-k]\sim s[i+k]\)中有 ...
- CodeForces - 528D Fuzzy Search (FFT求子串匹配)
题意:求母串中可以匹配模式串的子串的个数,但是每一位i的字符可以左右偏移k个位置. 分析:类似于 UVALive -4671. 用FFT求出每个字符成功匹配的个数.因为字符可以偏移k个单位,先用尺取法 ...
随机推荐
- [数据库] SQL查询语句表行列转换及一行数据转换成两列
原文来自:http://blog.csdn.net/Eastmount/article/details/50559008 本文主要讲述了SQL查询语句表之间的行列转换,同时也包括如何将一行数据转换成两 ...
- 制作ssh互信的docker镜像
Dockerfile FROM ubuntu:16.04 # package RUN apt-get update; apt-get -y install ssh COPY ssh_config /e ...
- [随笔] 简单操作解决Google chrome颜色显示不正常的情况
最近在用Linuxmint 真的是极友好的桌面Linux啊,然后用最新的Linuxmint自带的Firefox浏览器上网,发现颜色都变成了红色黄色变绿色,以为是显卡的问题,搞了一阵,无果.果断换Goo ...
- 邓_ Jqery·笔记本【照片】
-------------------------------------------------------------------------------------------- [PHP] - ...
- OKMX6Q在ltib生成的rootfs基础上制作带QT库的根文件系统
ltib每次执行后会在其目录下生成rootfs目录,并以其为基础生成rootfs.ext2.gz文件,而litb自带的QT库又太老,所以想到按照飞凌的<OKMX6X-S2-Qt4.8.5移植手册 ...
- 数据库复习总结(17)-T-Sql编程
T-SQL(SQL SERVER) 百度百科:(即 Transact-SQL,是 SQL 在 Microsoft SQL Server 上的增强版,它是用来让应用程序与 SQL Server 沟通的主 ...
- web前端学习(2):开始编写HTML
在第一章中,我们初步了解了上网的过程,同时也明白了所谓网页,其本质就是主要用HTML语言所写的一份文档.相信大多数人在了解HTML文件前,最先接触的是利用"记事本"所写的文档或者是 ...
- UML图学习之三 状态图
状态图(Statechart Diagram)主要用于描述一个对象在其生存期间的动态行为,表现为一个对象所经历的状态序列,引起状态转移的事件(Event),以及因状态转移而伴随的动作(Action). ...
- 更改sql多条数据,更新替换字符串中固定的字符串
需求产生的背景: 数据库里建库时插入了字典数据,可是这个字典数据,有一些是不准确的,所以就需要把一些固定的数据查出来替换掉. 问题解决逻辑: 大体逻辑是,首先把固定需要替换的字符串提取出来,赋值给变量 ...
- 新装Centos7.2 配置防火墙
1.安装 yum -y install firewalld2.开机启动 systemctl enable firewalld3.设置防火墙规则 systemctl restart firewalld ...