CF528D Fuzzy Search 字符串匹配+FFT
题意:
DNA序列,在母串s中匹配模式串t,对于s中每个位置i,只要s[i-k]到s[i+k]中有c就认为匹配了c。求有多少个位置匹配了t。
分析:
这个字符串匹配的方式,什么kmp,各种自动机都不灵。
所以有一个邪门功夫,fft字符串匹配。(做过洛谷《残缺的字符串》一题的应该都不陌生,带通配符的匹配字符串可以用fft卷积来做)
首先,由于字符集大小只有4,所以我们可以对每个字符分别考虑。
根据题意,对于每个字符,我们预处理a[i]数组,代表i位置是否能匹配当前字符(左右k个能匹配也算)
之后b[i]数组,保存t[i]位置的字符是不是c。
然后将b数组倒过来,fft做一下卷积,把答案累计起来检查总和是不是m就可以判断是否匹配。
代码:
#include<bits/stdc++.h>
#define db double
#define cp complex<db>
using namespace std;
const int N=;
const db pi=acos(-);
int ans,ton[N],n,m,k,lm,L,r[N];
char s[N],t[N];cp a[N],b[N];
void init(){
scanf("%d%d%d%s%s",&n,&m,&k,s,t);
} void fft(cp *f,int op){
for(int i=;i<lm;i++)
if(i>r[i]) swap(f[i],f[r[i]]);
for(int l=;l<lm;l<<=){
cp wn(cos(pi/l),op*sin(pi/l));
for(int i=;i<lm;i+=(l<<)){
cp w(,);
for(int j=;j<l;j++,w*=wn){
cp T=w*f[i+j+l];
f[i+j+l]=f[i+j]-T;f[i+j]+=T;
}
}
} if(op==-) for(int i=;i<lm;i++) f[i]/=lm;
} void calc(char c){
memset(a,,sizeof(a));memset(b,,sizeof(b));
int cnt=;
for(int i=;i<k;i++) cnt+=(s[i]==c);
for(int i=;i<n;i++){
if(i+k<n) cnt+=(s[i+k]==c);
if(i-k->=) cnt-=(s[i-k-]==c);
a[i]=cnt>?:;cout<<a[i]<<" ";
} for(int i=;i<m;i++) b[i]=(t[i]==c);puts("");
fft(a,);fft(b,);
for(int i=;i<lm;i++) a[i]*=b[i];
fft(a,-);for(int i=;i<=n-m;i++)
ton[i]+=(int)(a[i+m-].real()+0.5);
} void solve(){
for(lm=;lm<=n+m-;lm<<=,L++);
for(int i=;i<lm;i++)
r[i]=(r[i>>]>>)|((i&)<<(L-));
reverse(t,t+m);calc('A');
calc('G');calc('C');calc('T');
for(int i=;i<=n-m;i++) if(ton[i]==m) ans++;
printf("%d\n",ans);
} int main(){
init();solve();return ;
}
fft字符串匹配
CF528D Fuzzy Search 字符串匹配+FFT的更多相关文章
- CF528D. Fuzzy Search [FFT]
CF528D. Fuzzy Search 题意:DNA序列,在母串s中匹配模式串t,对于s中每个位置i,只要s[i-k]到s[i+k]中有c就认为匹配了c.求有多少个位置匹配了t 预处理\(f[i][ ...
- CF-528D Fuzzy Search(FFT字符串匹配)
Fuzzy Search 题意: 给定一个模式串和目标串按下图方式匹配,错开位置不多于k 解题思路: 总共只有\(A C G T\)四个字符,那么我们可以按照各个字符进行匹配,比如按照\(A\)进行匹 ...
- CF528D Fuzzy Search 和 BZOJ4259 残缺的字符串
Fuzzy Search 给你文本串 S 和模式串 T,求 S 的每个位置是否能模糊匹配上 T. 这里的模糊匹配指的是把 T 放到 S 相应位置上之后,T 中每个字符所在位置附近 k 个之内的位置上的 ...
- 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]\)可 ...
- 【CF528D】Fuzzy Search(FFT)
[CF528D]Fuzzy Search(FFT) 题面 给定两个只含有\(A,T,G,C\)的\(DNA\)序列 定义一个字符\(c\)可以被匹配为:它对齐的字符,在距离\(K\)以内,存在一个字符 ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
- 【Codeforces528D】Fuzzy Search FFT
D. Fuzzy Search time limit per test:3 seconds memory limit per test:256 megabytes input:standard inp ...
随机推荐
- MFC类别概述
MFC 类别主要可分为下列数大群组: ■ General Purpose classes - 提供字符串类别.数据处理类别(如数组与串行),异 常情况处理类别.文件类别...等等. ■ Windows ...
- 51nod1266【水】
最短,两半分开走 最长,一边走,比较一下两端就好了. #include <bits/stdc++.h> using namespace std; typedef long long LL; ...
- bzoj 4161 Shlw loves matrixI【常系数线性齐次递推】
并不会递推,不过板子挺好背的,只要是类似的递推都能用,但是注意c数组不能使负数 如果除了递推还有常数项的话,就用f[i]-f[i-1]的方式消掉常数项(然后多一个f[i-1]的项) #include& ...
- 51Nod 1649 齐头并进
#include <iostream> #include <algorithm> #include <cstring> //两遍迪杰斯特拉 #define INF ...
- 洛谷 P2714 四元组统计
错误记录:42行N写成n:事实上除了读入以外,此题的小n没有任何用途 #include<cstdio> #include<algorithm> #include<cstr ...
- 在sz
在大城市,sz, 每天骑单车去公交车站. 每天用高德地图 坐快线巴士 车上下班要3个小时. 用guomei 的回收管家 回收 旧空调. 我在kfc 看书 在班车上睡觉/眯眼 在办公室睡觉,看书,工作 ...
- 168 Excel Sheet Column Title Excel表列名称
给定一个正整数,返回它在Excel表中相对应的列名称.示例: 1 -> A 2 -> B 3 -> C ... 26 -> Z 27 -&g ...
- ubuntu16.04里如何正确添加用root用户来登录图形界面(图文详解)
不多说,直接上干货! Ubuntu版本都默认不允许使用root登录,必须要改配置文件. 第一步: 首先设置root密码,利用现有管理员帐户登陆Ubuntu,在终端执行命令:sudo passwd ro ...
- c++ 如何对拍
首先要写好两个要对拍程序(假设是A,B),和一个制造数据的程序(设为made) (要放在同一文件夹内) 编译得到A.exe , B.exe , made.exe 写一个对拍器 格式如下 @ech ...
- jQuery选择器之基本筛选选择器
<h2>基本筛选器</h2> <h3>:first/:last/:even/:odd</h3> <div class="left&quo ...