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 ...
随机推荐
- 追书神器API
由于自己喜欢看小说,有的时候不方便手机看的时候希望在电脑上面看,但很多网站有广告啊,于是封装了套手机版的追书神器API 目前只做了搜索 详情 书评 换源 正文 调用方式: //搜索小说 var sea ...
- Android性能优化来龙去脉总结
WeTest 导读 一款app除了要有令人惊叹的功能和令人发指交互之外,在性能上也应该追求丝滑的要求,这样才能更好地提高用户体验. 以下是本人在工作中对经历过的性能优化的一些总结,依据故事的发展路线, ...
- 「知识学习」二分图的最大匹配、完美匹配和匈牙利算法(HDU-2063)
定义 如果一个图\((E,V)\)的顶点集\(E\)能够被能够被分成两个不相交的集合\(X,Y\),且每一条边都恰连接\(X,Y\)中的各一个顶点,那么这个图就是一个二分图. 容易得知,它就是不含有奇 ...
- 180611-Spring之RedisTemplate配置与使用
logo 文章链接:https://liuyueyi.github.io/hexblog/2018/06/11/180611-Spring之RedisTemplate配置与使用/ Spring ...
- 使用pycharm软件配置数据库可视化
必须品: pycharm软件,专业版最好自带就有,社区版就需要安装下插件. 专业版直接会在右边的编辑框浮动,直接点开就可以配置. 如图所示,点开就可以配置相应的数据库, 点开配置完毕就可以使用了. 还 ...
- 关于java中“使用了未经检查或不安全的操作、有关详细信息,请使用 ——Xlint:unchecked重新编译”
今天看<算法 第4版>排序章节时,发现了一个了一个小问题.先贴一下代码: public class Selection{ public static void main(String[]a ...
- kaldi - Online Audio Server(服务器客户端建立方法-旧版在线解码)
目录 一.服务器客户端识别系统建立方法 1. Command line to start the server(服务器端启动方式): 2. Command line to start the clie ...
- vmware安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题
虚拟机使用的是VMware Workstation,并且首次在虚拟机体验64 位系统.在新建好虚拟机,运行时候就出现了VMware Workstation 的提醒:此主机支持 Intel VT-x,但 ...
- nginx配置和网站的部署
环境: CentOS Linux release 7.3.1611 (Core) nginx version: nginx/1.13.4 PHP 5.4.16 (cli) (built: Nov 6 ...
- Bus of Characters(栈和队列)
In the Bus of Characters there are nn rows of seat, each having 22 seats. The width of both seats in ...
