【Codeforces528D】Fuzzy Search FFT
D. Fuzzy Search
Leonid works for a small and promising start-up that works on decoding the human genome. His duties include solving complex problems of finding certain patterns in long strings consisting of letters 'A', 'T', 'G' and 'C'.
Let's consider the following scenario. There is a fragment of a human DNA chain, recorded as a string S. To analyze the fragment, you need to find all occurrences of string T in a string S. However, the matter is complicated by the fact that the original chain fragment could contain minor mutations, which, however, complicate the task of finding a fragment. Leonid proposed the following approach to solve this problem.
Let's write down integer k ≥ 0 — the error threshold. We will say that string T occurs in string S on position i (1 ≤ i ≤ |S| - |T| + 1), if after putting string T along with this position, each character of string T corresponds to the some character of the same value in string S at the distance of at most k. More formally, for any j (1 ≤ j ≤ |T|) there must exist such p (1 ≤ p ≤ |S|), that |(i + j - 1) - p| ≤ k and S[p] = T[j].
For example, corresponding to the given definition, string "ACAT" occurs in string "AGCAATTCAT" in positions 2, 3 and 6.

Note that at k = 0 the given definition transforms to a simple definition of the occurrence of a string in a string.
Help Leonid by calculating in how many positions the given string T occurs in the given string S with the given error threshold.
Input
The first line contains three integers |S|, |T|, k (1 ≤ |T| ≤ |S| ≤ 200 000, 0 ≤ k ≤ 200 000) — the lengths of strings S and T and the error threshold.
The second line contains string S.
The third line contains string T.
Both strings consist only of uppercase letters 'A', 'T', 'G' and 'C'.
Output
Print a single number — the number of occurrences of T in S with the error threshold k by the given definition.
Examples
10 4 1
AGCAATTCAT
ACAT
output
3
Note
If you happen to know about the structure of the human genome a little more than the author of the problem, and you are not impressed with Leonid's original approach, do not take everything described above seriously.
Solution
题目大意:给出A,B串,求B串在A串中出现的次数.这里的A串有奇怪的性质,对于一个位置$i$,只要$[i-k,i+k]$中存在合法匹配B中一个字符,则可以认为$i$位置匹配。字符集大小AGCT
毛啸论文里的例题,FFT的简单应用。 详细的看论文吧..
Code
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
#define MAXN 800010
#define Pai acos(-1.0)
map<char,int>id;
char a[MAXN],b[MAXN];
int ok[MAXN][5],cnt[5],N,M,K,ans[MAXN],len;
struct Complex{
double r,i;
Complex (double R=0.0,double I=0.0) {r=R,i=I;}
Complex operator + (const Complex & A) const {return Complex(r+A.r,i+A.i);}
Complex operator - (const Complex & A) const {return Complex(r-A.r,i-A.i);}
Complex operator * (const Complex & A) const {return Complex(r*A.r-i*A.i,r*A.i+i*A.r);}
};
Complex A[MAXN],B[MAXN],C[MAXN];
inline void Prework(int j)
{
len=1;
while (len<(N<<1)) len<<=1;
for (int i=0; i<N; i++) A[i]=Complex(ok[i+1][j],0);
for (int i=N; i<len; i++) A[i]=Complex(0,0);
// for (int i=0; i<len; i++) printf("%d ",(int)(A[i].r+0.5)); puts("");
for (int i=0; i<M; i++) B[i]=Complex(id[b[M-i]]==j,0);
for (int i=M; i<len; i++) B[i]=Complex(0,0);
// for (int i=0; i<len; i++) printf("%d ",(int)(B[i].r+0.5)); puts("");
}
inline void Rader(Complex *x)
{
for (int i=1,j=len>>1,k; i<len-1; i++)
{
if (i<j) swap(x[i],x[j]);
k=len>>1;
while (j>=k) j-=k,k>>=1;
if (j<k) j+=k;
}
}
inline void DFT(Complex *x,int opt)
{
Rader(x);
for (int h=2; h<=len; h<<=1)
{
Complex Wn( cos(opt*2*Pai/h) , sin(opt*2*Pai/h) );
for (int i=0; i<len; i+=h)
{
Complex W(1,0);
for (int j=i; j<i+h/2; j++)
{
Complex u=x[j],t=x[j+h/2]*W;
x[j]=u+t; x[j+h/2]=u-t;
W=W*Wn;
}
}
}
if (opt==-1)
for (int i=0; i<len; i++) x[i].r/=len;
}
inline void FFT(Complex *A,Complex *B,Complex *C)
{
DFT(A,1); DFT(B,1);
for (int i=0; i<len; i++) C[i]=A[i]*B[i];
DFT(C,-1);
for (int i=0; i<len; i++) ans[i]+=(int)(C[i].r+0.5);
}
int main()
{
id['A']=1,id['G']=2,id['C']=3,id['T']=4;
scanf("%d%d%d%s%s",&N,&M,&K,a+1,b+1);
int l=0,r=0;
for (int i=1; i<=N; i++)
{
while (l<N && l<i-K) cnt[id[a[l++]]]--;
while (r<N && r<i+K) cnt[id[a[++r]]]++;
for (int j=1; j<=4; j++) if (cnt[j]) ok[i][j]=1;
}
// for (int i=1; i<=N; i++) printf("%d %d %d %d\n",ok[i][1],ok[i][2],ok[i][3],ok[i][4]);
for (int j=1; j<=4; j++) Prework(j),FFT(A,B,C);
int Ans=0;
for (int i=0; i<len; i++) if (ans[i]==M) Ans++;
printf("%d\n",Ans);
return 0;
}
【Codeforces528D】Fuzzy Search FFT的更多相关文章
- 【CF528D】Fuzzy Search(FFT)
[CF528D]Fuzzy Search(FFT) 题面 给定两个只含有\(A,T,G,C\)的\(DNA\)序列 定义一个字符\(c\)可以被匹配为:它对齐的字符,在距离\(K\)以内,存在一个字符 ...
- 【CF528D】Fuzzy Search
Problem Description 你有一个长度为 \(n\) 的串 \(S\),以及长度为 \(m\) 的串 \(T\). 现给定一个数 \(k\) ,我们说 \(T\) 在 \(S\) 的位置 ...
- 【HDU2222】Keywords Search AC自动机
[HDU2222]Keywords Search Problem Description In the modern time, Search engine came into the life of ...
- 【BZOJ3160】万径人踪灭(FFT,Manacher)
[BZOJ3160]万径人踪灭(FFT,Manacher) 题面 BZOJ 题解 很容易想到就是满足条件的子序列个数减去回文子串的个数吧... 至于满足条件的子序列 我们可以依次枚举对称轴 如果知道关 ...
- 【BZOJ3527】力(FFT)
[BZOJ3527]力(FFT) 题面 Description 给出n个数qi,给出Fj的定义如下: \[Fj=\sum_{i<j}\frac{q_i q_j}{(i-j)^2 }-\sum_{ ...
- 【BZOJ4827】【HNOI2017】礼物(FFT)
[BZOJ4827][HNOI2017]礼物(FFT) 题面 Description 我的室友最近喜欢上了一个可爱的小女生.马上就要到她的生日了,他决定买一对情侣手 环,一个留给自己,一 个送给她.每 ...
- 【计算机视觉】Selective Search for Object Recognition论文阅读3
Selective Search for Object Recoginition surgewong@gmail.com http://blog.csdn.net/surgewong 在前 ...
- 【Matlab】快速傅里叶变换/ FFT/ fftshift/ fftshift(fft(fftshift(s)))
[自我理解] fft:可以指定点数的快速傅里叶变换 fftshift:将零频点移到频谱的中间 用法: Y=fftshift(X) Y=fftshift(X,dim) 描述:fftshift移动零频点到 ...
- 【HDU2222】Keywords Search(AC自动机)
Problem Description In the modern time, Search engine came into the life of everybody like Google, B ...
随机推荐
- ubuntu更新源列表
1. 备份源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list_backup 2.修改更新源 打开源列表 sudo gedit /etc/ap ...
- mysql修改表的存储引擎(myisam<=>innodb)【转】
修改表的存储引擎myisam<=>innodb 查看表的存储引擎mysql> show create table tt7;+-------+--------------------- ...
- TreeCollection2
Tree Collection 2 Table of Contents Introduction Structure Interfaces Data Node structure Tree struc ...
- MVVM设计模式的事件绑定
为什么要事件绑定 这个问题其实是很好理解的,因为事件是丰富多样的,单纯的命令绑定远不能覆盖所有的事件.例如Button的命令绑定能够解决Click事件的需求,但Button的MouseEnter.窗体 ...
- angular架构
angular架构包括以下部分: 1.模块 2.组件 3.模板 4.元数据 5.数据绑定 6.指令 7.服务 8.依赖注入 9.动画 10.变更检测 11.事件 12.表单 13.HTTP 14.生命 ...
- Mat结构
主要是记录一下大牛的博客,再次感谢这些无私的博主. 这篇博客http://blog.csdn.net/yang_xian521/article/details/7107786中,我觉得要注意的是Mat ...
- 序列化 json和pickle
序列化 1. 什么叫序列化 将原本的字典.列表等内容转换成一个字符串的过程就叫做序列化. 2. json dumps loads 一般对字典和列表序列化 dump load 一般对 ...
- jquery跨域请求事例
//js发送跨域请求部分var requesturl = 'url'; $.ajax({ type:'GET', url:requesturl, data:{'qNum':num}, dataType ...
- Observer 观察者
意图 定义对象间的一种一对多的依赖关系 ,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新. 动机 一致性,松耦合 需要维护相关对象间的一致性.我们不希望为了维持一致性而使各类紧 ...
- 基于centos6构建私有gitbook平台
前言: 开源gitbook工具可以让你方便有效的管理自己的文章笔记.发布产品文档等.这里为了学习,基于centos系统构建一个私有的gitbook项目.与公有云gitbook平台相比,这里是简单的展示 ...