【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 ...
随机推荐
- 关于new Handler()与new Handler(Looper.getMainLooper())区别
如果你不带参数的实例化:Handler handler=new Handler();那么这个会默认用当前线程的Looper对象. 一般而言,如果你的Handler是要用来刷新UI的,那么就需要在主线程 ...
- vue实现结算淘宝购物车效果
实现单选时的价格,全选时价格 单选效果图 全选效果图 html <template> <!-- 淘宝结算购物车 --> <div class="settleme ...
- js实现数据视图双向绑定原理
这个方法了不起啊..vue.js和avalon.js 都是通过它实现双向绑定的..而且Object.observe也被草案发起人撤回了..所以defineProperty更有必要了解一下了几行代码看他 ...
- 【前端开发】限制input输入保留两位小数
<input type="text" name='amount' id="cash_num" placeholder="请输入金额" ...
- python基础-类的其他方法
一.isinstance(obj,cls)检查是否obj是类的cls对象 # -*- coding:utf-8 -*- __author__ = 'shisanjun' class Foo(objec ...
- virtualenv,virtualenvwrapper安装及使用
1.安装 # 安装: (sudo) pip install virtualenv virtualenvwrapper # centos7下 pip install virtualenv virtual ...
- Spring 事务管理基础知识点
参考文章 spring事物配置,声明式事务管理和基于@Transactional注解的使用 尚硅谷 佟刚 Spring视频教程PPT Spring支持编程式事务管理和声明式事务管理两种方式 编程式事务 ...
- 20165203实验四 Andriod程序设计
20165203实验四 Andriod程序设计 实验内容 安装 Android Stuidio 学习Android Stuidio调试应用程序 实验要求 1.没有Linux基础的同学建议先学习< ...
- 实时流计算、Spark Streaming、Kafka、Redis、Exactly-once、实时去重
http://lxw1234.com/archives/2018/02/901.htm
- 【BZOJ】4671: 异或图
题解 写完之后开始TTTTTTT--懵逼 这道题我们考虑一个东西叫容斥系数啊>< 这个是什么东西呢 也就是\(\sum_{i = 1}^{m}\binom{m}{i}f_{i} = [m ...