51NOD 1565:模糊搜索——题解
http://www.51nod.com/onlineJudge/questionCode.html#problemId=1565¬iceId=445588
有两个基因串S和T,他们只包含AGCT四种字符。现在你要找出T在S中出现了几次。
有一个门限值k≥0。T在S的第i(1≤i≤|S|-|T|+1)个位置中出现的条件如下:把T的开头和S的第i个字符对齐,然后T中的每一个字符能够在S中找到一样的,且位置偏差不超过k的,那么就认为T在S的第i个位置中出现。也就是说对于所有的 j (1≤j≤|T|),存在一个 p (1≤p≤|S|),使得|(i+j-1)-p|≤k 和[p]=T[j]都成立。
例如,根据这样的定义"ACAT"出现在"AGCAATTCAT"的第2,3和6的位置。
如果k=0,那么这个就是经典的字符串匹配问题。
现在给定门限和两个基因串S,T,求出T在S中出现的次数。
参考:https://www.cnblogs.com/ivorysi/p/9185805.html
首先用差分/线段树处理出每个位置是否能够匹配A/T/C/G,令$a[i][j]$存之,表示$i$这个字符在$j$这个位置是否能被匹配上。
然后我们处理模式串,令$b[i][j]$表示$i$这个字符在$j$这个位置是否存在。
然后就是套路了:BZOJ4259:残缺的字符串对大部分模糊匹配都是一个套路。
我们将模式串倒置然后末尾补0,令:
$f[k][i]=\sum_{j=0}^i(b[k][j]-a[k][i-j])b[k][j]$,当$f[k][j]==0$时说明我们只看$k$字符时模式串能被以$i$为终点的字符串所匹配上。
(我们后面多乘的那个是为了防止该位置不存在$k$字符所设置的。)
展开得到:
$f[k][i]=\sum_{j=0}^ib[k][j]^2-\sum_{j=0}^ia[k][i-j]b[k][j]$
后者是一个卷积,可以直接FFT,前者的2次方其实也可以直接拿掉(因为$1^2=1,0^2=0$)
显然当所有的字符情况下均满足$f[i]==0$的时候$i$就是一个合法位点了。
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef double dl;
const int N=4e5+;
const dl pi=acos(-1.0);
const int INF=;
struct complex{
dl x,y;
complex(dl xx=0.0,dl yy=0.0){
x=xx,y=yy;
}
complex operator +(const complex &b)const{
return complex(x+b.x,y+b.y);
}
complex operator -(const complex &b)const{
return complex(x-b.x,y-b.y);
}
complex operator *(const complex &b)const{
return complex(x*b.x-y*b.y,x*b.y+y*b.x);
}
};
void FFT(complex a[],int n,int on){
for(int i=,j=n>>;i<n-;i++){
if(i<j)swap(a[i],a[j]);
int k=n>>;
while(j>=k){j-=k;k>>=;}
if(j<k)j+=k;
}
for(int i=;i<=n;i<<=){
complex res(cos(-*pi*on/i),sin(-*pi*on/i));
for(int j=;j<n;j+=i){
complex w(,);
for(int k=j;k<j+i/;k++){
complex u=a[k],t=w*a[k+i/];
a[k]=u+t;a[k+i/]=u-t;
w=w*res;
}
}
}
if(on==-)
for(int i=;i<n;i++)a[i].x/=n;
}
inline int turn(char ch){
if(ch=='A')return ;
if(ch=='G')return ;
if(ch=='C')return ;
return ;
}
char s1[N],s2[N];
int n,m,k,t[N][];
int a[][N],b[][N],ans[N];
complex A[N],B[N];
bool can[N];
int main(){
scanf("%d%d%d",&n,&m,&k);
scanf("%s%s",s1,s2);
for(int i=;i<n;i++){
int w=turn(s1[i]);
int l=max(,i-k),r=min(n-,i+k);
t[l][w]++;t[r+][w]--;
}
for(int i=;i<n;i++)
for(int j=;j<;j++){
if(i)t[i][j]+=t[i-][j];
if(t[i][j]>)a[j][i]=;
}
for(int i=;i<m;i++)b[turn(s2[m-i-])][i]=; int len=;
while(len<n)len<<=;
for(int i=;i<;i++){
for(int j=;j<n;j++)
ans[j]=(j?ans[j-]:)+b[i][j]; for(int j=;j<len;j++){
A[j]=complex(a[i][j],);
B[j]=complex(b[i][j],);
}
FFT(A,len,);FFT(B,len,);
for(int j=;j<len;j++)A[j]=A[j]*B[j];
FFT(A,len,-);
for(int j=;j<n;j++)ans[j]-=(int)(A[j].x+0.5); for(int j=;j<n;j++)if(ans[j])can[j]=;
}
int cnt=;
for(int i=m-;i<n;i++)if(!can[i])cnt++;
printf("%d\n",cnt);
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
51NOD 1565:模糊搜索——题解的更多相关文章
- 51nod 1565 模糊搜索 FFT
这...好强啊\(QwQ\) 思路:卷积?\(FFT\)? 提交:\(5\)次 错因:一开始的预处理写错了(竟然只错了最后几个大点)闹得我以为\(FFT\)写挂了\(QwQ\) 题解: 对四种字符分开 ...
- 51nod 1565模糊搜索(FFT)
题目大意就是字符串匹配,不过有一个门限k而已 之前有提到过fft做字符串匹配,这里和之前那种有些许不同 因为只有A,C,G,T四种字符,所以就考虑构造4个01序列 例如,模板串a关于'A'的01序列中 ...
- 【51nod】1565 模糊搜索
题解 这个字符集很小,我们可以把每个字符拿出来做一次匹配,把第一个字符串处理每个出现过的该字符处理成一个区间加,即最后变成第一个字符串的该位置能够匹配某字符 例如对于样例 10 4 1 AGCAATT ...
- 胡小兔的OI日志3 完结版
胡小兔的 OI 日志 3 (2017.9.1 ~ 2017.10.11) 标签: 日记 查看最新 2017-09-02 51nod 1378 夹克老爷的愤怒 | 树形DP 夹克老爷逢三抽一之后,由于采 ...
- 51Nod1518 稳定多米诺覆盖 动态规划 插头dp 容斥原理
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1518.html 题目传送门 - 51Nod1518 题意 51Nod真是个好OJ ,题意概括的真好, ...
- HDU 6153 A Secret ( KMP&&DP || 拓展KMP )
题意 : 给出两个字符串,现在需要求一个和sum,考虑第二个字符串的所有后缀,每个后缀对于这个sum的贡献是这个后缀在第一个字符串出现的次数*后缀的长度,最后输出的答案应当是 sum % 1e9+7 ...
- 51nod图论题解(4级,5级算法题)
51nod图论题解(4级,5级算法题) 1805 小树 基准时间限制:1.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 她发现她的树的点上都有一个标号(从1到n),这些树都在空 ...
- 51nod 1812 树的双直径 题解【树形DP】【贪心】
老了-稍微麻烦一点的树形DP都想不到了. 题目描述 给定一棵树,边权是整数 \(c_i\) ,找出两条不相交的链(没有公共点),使得链长的乘积最大(链长定义为这条链上所有边的权值之和,如果这条链只有 ...
- 51NOD 1773:A国的贸易——题解
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1773 参考1:FWT讲解 https://www.cnblogs.com ...
随机推荐
- memory引擎和innodb引擎速度对比
ysql> insert into innodb_test (name) select name from innodb_test; Query OK, rows affected ( min ...
- 消费者用nginx做负载均衡,提供者用zookeeper自带功能实现负载均衡
公司的项目基于阿里的Dubbo微服务框架开发.为了符合相关监管部门的安全要求,公司购买了华东1.华东2两套异地服务器,一套是业务服务器,一套是灾备服务器.准备在这两套服务器上实现Dubbo的分布式服务 ...
- 第五模块:WEB开发基础 第2章·JavaScript基础
01-JavaScript的历史发展过程 02-js的引入方式和输出 03-命名规范和变量的声明定义 04-五种基本数据类型 05-运算符 06-字符串处理 07-数据类型转换 08-流程控制语句if ...
- OIDC in Angular 6
参照 草根专栏- ASP.NET Core + Ng6 实战:https://v.qq.com/x/page/i07702h18nz.html 1. OIDC-Client https://githu ...
- 论文笔记:Deep Attentive Tracking via Reciprocative Learning
Deep Attentive Tracking via Reciprocative Learning NIPS18_tracking Type:Tracking-By-Detection 本篇论文地主 ...
- 欢迎来怼--第七次Scrum会议
一.小组信息 队名:欢迎来怼 小组成员: 队长:田继平 成员:李圆圆,葛美义,王伟东,姜珊,邵朔,冉华 小组照片 二.开会信息 时间:2017/10/19 17:05~17:17,总计12min. 地 ...
- coding.net 版本控制
这是版本测试的所有内容,其中用到了 git 和coding的远程连接. 代码及版本控制 git地址:https://git.coding.net/tianjiping/11111.git
- c#笔记整理 关于继承与多态等
[ 塔 · 第 二 条 约 定 ] c#面向对象基础 整理private.protected.public.abstract等的异同 public 公有访问.不受任何限制. private 私有访问. ...
- 将代码上传到GitHub
网上看了很多资料,都是用的命令行,比较难看懂,自己摸索了一下怎么样在图形界面上操作.下面记录的只是简单的如何把本地仓库直接上传到服务器上. 在mac上下载个GitHub Mac客户端,安装好后运行,输 ...
- <Android>tab选项卡
1.继承TabActivity实现 a) 在布局文件中使用FrameLayout列出Tab组件及Tab中的内容组件 b) Activity要继承TabActivity c ...
