一句话题意

给你两个串s、t,长度为n、m,字符集为"ATGC",当且仅

当[i - k; i + k]中存在一个j,使得s[j ] = t[x]时,s[i ]可以

和t[x]匹配,问t总共能与s的几个子串匹配

首先,字符集只有4,那么,令s_A[i]=0/1 表示在s中i位置能否和A匹配,同理t_A[i];

一类关于通配符匹配的字符串问题都是可以用FFT来解决的

以A字符为例,令

\[C[i]=\sum_{j=0}^{m-1}S[i+j]*T[j] , D=\sum_{i=0}^{m-1}T[i]
\]

则当c[i]==D时 以S[i]为首的一个子串内的A的位置与T的A的位置相同

\[T'[m-j-1]=T[j] , C'[m+i-1]=C[i]
\]

代入原式,则

\[C'[m+i-1]=\sum_{j=0}^{m-1}S[i+j]*T[m-j-1]
\]

成为了卷积形式

P.S. 也可以用bitset

#include<bits/stdc++.h>

using namespace std;

namespace Tzh{

	typedef double dd;
const char ch[]="0ATCG";
const int maxn=700010;
const dd pi=acos(-1);
int ans,vis[maxn],x,y,k,rev[maxn],n=1,len,sum;
string S,T; struct complex{
dd x,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};
}
complex operator *(const complex &b) const{
return (complex){x*b.x-y*b.y,x*b.y+y*b.x};
}
void init(){
x=0,y=0;
}
}s[maxn],t[maxn]; void init(){
for(int i=0;i<n;i++)
rev[i]=rev[i>>1]>>1|((i&1)<<(len-1));
} complex omg(int x,int flag){
return (complex){cos((dd)x*2*pi/n),(dd)sin((dd)x*2*pi/n)*flag};
} void FFT(complex *a,int type){
for(int i=0;i<n;i++) if(rev[i]>i) swap(a[i],a[rev[i]]);
for(int l=2,m=1;l<=n;m=l,l<<=1)
for(int i=0;i<n;i+=l)
for(int j=0;j<m;j++){
complex tt=omg(n/l*j,type)*a[i+j+m];
a[i+j+m]=a[i+j]-tt,a[i+j]=a[i+j]+tt;
}
if(type==-1)
for(int i=0;i<n;i++) a[i].x/=n;
} void work(){
ios::sync_with_stdio(false);
cin>>x>>y>>k;
cin>>S>>T; for(int i=0;i<=x;i++) vis[i]=1;
while(n<=x+y) n<<=1,len++; init();
for(int j=1;j<=4;j++){ int num=0;
for(int i=0;i<S.size();i++){
if(S[i]==ch[j]) num++;
if(i>k&&S[i-k-1]==ch[j]) num--;
s[i].x=(dd)(num>0);
} num=0,sum=0;
for(int i=S.size()-1;i>=0;i--){
if(S[i]==ch[j]) num++;
if(i+k+1<S.size()&&S[i+k+1]==ch[j]) num--;
s[i].x=max(s[i].x,(dd)(num>0));
}
for(int i=0;i<T.size();i++)
t[y-i-1].x=(dd)(T[i]==ch[j]),sum+=(int)t[y-i-1].x;
FFT(s,1),FFT(t,1);
for(int i=0;i<n;i++) s[i]=s[i]*t[i]; FFT(s,-1);
for(int i=0;i<x;i++) if((int)((dd)s[y+i-1].x+0.5)!=sum) vis[i]=0;
for(int i=0;i<n;i++) s[i].init(),t[i].init();
}
for(int i=0;i<x;i++) ans+=vis[i];
cout<<ans<<endl;
return ;
}
} int main(){
// freopen("1.in","r",stdin);
Tzh::work();
return 0;
}

CF_528D的更多相关文章

随机推荐

  1. eclipse导入java工程

    1)File下的import选项 2)点击General,选择Existing Projects into Workspace,点击next 3)点击Browse,在弹出的窗口中选择导入工程所在的文件 ...

  2. js高德地图手机定位

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...

  3. 介绍Dynamics 365的OrgDBOrgSettings工具

    摘要: 微软动态CRM专家罗勇 ,回复320或者20190320可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 有时候会需要 ...

  4. H3C交换机S5500划分VLAN

    好记性不如烂笔头! H3C交换机S5500划分VLAN       将H3C S5500换机现在需要分三网段,分别是VLAN14,VLAN15,VLAN16,交换机中默认全部口是VLAN1.   H3 ...

  5. IDEA XML注释与取消注释快捷键

    IntelliJ IDEA和eclipse中编辑Java文件时,注释和取消注释的快捷键都是: "CTRL + / " 编辑xml文件时, 注释:CTRL + SHIFT + / 取 ...

  6. 深入浅出KNN算法(一) KNN算法原理

    一.KNN算法概述 KNN可以说是最简单的分类算法之一,同时,它也是最常用的分类算法之一,注意KNN算法是有监督学习中的分类算法,它看起来和另一个机器学习算法Kmeans有点像(Kmeans是无监督学 ...

  7. 简单的纯js三级联动

    参考这个  日尼禾尔  二级联动 写了三级联动 <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...

  8. bootstarp 多图片上传 带进度条

    前台代码如下: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head&g ...

  9. Visual Studio Code自定义快捷键(eclipse习惯)

    左下角设置按钮 -> Keyboard Shortcuts -> keybindings.json. [ { "key": "alt+/", &qu ...

  10. 禁用windows10自动更新

    更换win10系统后经常会自动更新,每次关机前都会提示关机并更新选项,禁用window update后每隔几天还是会出现 解决:同时禁用以下两项 Windows Update Medic Servic ...