CF 528D. Fuzzy Search NTT

题目大意

给出文本串S和模式串T和k,S,T为DNA序列(只含ATGC)。对于S中的每个位置\(i\),只要中[i-k,i+k]有一个位置匹配了字符\(i\),那么就认为\(i\)可以匹配。求S中有多少位置匹配了T。

思路

一共有四个字母,我们分别计算每个字母是否可行,其他不管。

最后四个都满足的位置就是一个合法位置(指的是初始位置)。

设g[i]表示S_i位置是否是枚举的字母,f[i]表示M_i是否是是枚举的字母。

他们满足条件只需要右斜对角线==len

发现每个点又是右斜对角线,反转ntt

错误

有点zz,4写成了m,还忘记删掉调试了,wrong了两发,ntt真好调试(不用调试)。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+7,mod=998244353;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,m,k,limit=1,l,r[N];
char S[N],T[N];
int q_pow(int a,int b) {
int ans=1;
while(b) {
if(b&1) ans=1LL*ans*a%mod;
a=1LL*a*a%mod;
b>>=1;
}
return ans;
}
void ntt(int *a,int type) {
for(int i=0;i<=limit;++i)
if(i<r[i]) swap(a[i],a[r[i]]);
for(int mid=1;mid<limit;mid<<=1) {
int Wn=q_pow(3,(mod-1)/(mid<<1));
for(int i=0;i<limit;i+=(mid<<1)) {
for(int j=0,w=1;j<mid;j++,w=1LL*w*Wn%mod) {
int x=a[i+j],y=1LL*w*a[i+j+mid]%mod;
a[i+j]=(x+y)%mod;
a[i+j+mid]=(x+mod-y)%mod;
}
}
}
if(type==-1) {
reverse(&a[1],&a[limit]);
int inv=q_pow(limit,mod-2);
for(int i=0;i<=limit;++i) a[i]=1LL*a[i]*inv%mod;
}
}
int AAA[N],f[N],g[N],sum[N];
void solve(char x) {
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
int tong,h=0,d=0;
sum[0]=(S[0]==x);
for(int i=1;i<n;++i) sum[i]=sum[i-1]+(S[i]==x);
for(int i=0;i<n;++i) {
int y=i+k>=n ? sum[n-1] : sum[i+k];
int x=i-k-1 < 0 ? 0 : sum[i-k-1];
g[i]=(bool)(y-x);
}
for(int i=0;i<m;++i) f[m-i-1]=(T[i]==x);
// for(int i=0;i<n;++i) cout<<g[i]<<" ";cout<<"\n";
// for(int i=0;i<m;++i) cout<<f[i]<<" ";cout<<"\n"; ntt(g,1),ntt(f,1);
for(int i=0;i<=limit;++i) f[i]=1LL*f[i]*g[i]%mod;
ntt(f,-1);
int gs=0;
for(int i=0;i<m;++i) gs+=(T[i]==x);
for(int i=m-1,js=0;i<=n-1;++i,++js) AAA[js]+=(f[i]==gs);
}
int main() {
n=read(),m=read(),k=read();
scanf("%s%s",S,T);
while(limit<=n+m-2) limit<<=1,l++;
for(int i=0;i<=limit;++i)
r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
solve('A'),solve('T'),solve('G'),solve('C');
int tot=0;
for(int i=0;i<=n-m+1;++i) tot+=(AAA[i]==4);
printf("%d\n",tot);
return 0;
}

CF 528D. Fuzzy Search NTT的更多相关文章

  1. codeforces 528D Fuzzy Search

    链接:http://codeforces.com/problemset/problem/528/D 正解:$FFT$. 很多字符串匹配的问题都可以用$FFT$来实现. 这道题是要求在左边和右边$k$个 ...

  2. CodeForces 528D Fuzzy Search 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8782849.html 题目传送门 - CodeForces 528D 题意 给你两个串$A,B(|A|\geq| ...

  3. Codeforces 528D Fuzzy Search(FFT)

    题目 Source http://codeforces.com/problemset/problem/528/D Description Leonid works for a small and pr ...

  4. ●codeforces 528D Fuzzy Search

    题链: http://codeforces.com/problemset/problem/528/D 题解: FFT 先解释一下题意: 给出两个字符串(只含'A','T','C','G'四种字符),一 ...

  5. Codeforces.528D.Fuzzy Search(FFT)

    题目链接 \(Descripiton\) 给出文本串S和模式串T和k,S,T为DNA序列(只含\(A,T,G,C\)).对于S中的每个位置\(i\),只要\(s[i-k]\sim s[i+k]\)中有 ...

  6. 2019.01.26 codeforces 528D. Fuzzy Search(fft)

    传送门 fftfftfft好题. 题意简述:给两个字符串s,ts,ts,t,问ttt在sss中出现了几次,字符串只由A,T,C,GA,T,C,GA,T,C,G构成. 两个字符匹配的定义: 当si−k, ...

  7. CodeForces - 528D Fuzzy Search (FFT求子串匹配)

    题意:求母串中可以匹配模式串的子串的个数,但是每一位i的字符可以左右偏移k个位置. 分析:类似于 UVALive -4671. 用FFT求出每个字符成功匹配的个数.因为字符可以偏移k个单位,先用尺取法 ...

  8. CF528D. Fuzzy Search [FFT]

    CF528D. Fuzzy Search 题意:DNA序列,在母串s中匹配模式串t,对于s中每个位置i,只要s[i-k]到s[i+k]中有c就认为匹配了c.求有多少个位置匹配了t 预处理\(f[i][ ...

  9. 【Codeforces528D】Fuzzy Search FFT

    D. Fuzzy Search time limit per test:3 seconds memory limit per test:256 megabytes input:standard inp ...

随机推荐

  1. LeetCode 13 Roman to Integer 解题报告

    题目要求 Roman numerals are represented by seven different symbols: I, V, X, L, C, Dand M. Symbol Value ...

  2. boost::filesystem总结

    boost::filesystem是Boost C++ Libraries中的一个模块,主要作用是处理文件(Files)和目录(Directories).该模块提供的类boost::filesyste ...

  3. 制作自己的docker镜像

    制作自己的Docker镜像主要有如下两种方式: 1.使用docker commit 命令来创建镜像 通过docker run命令启动容器 修改docker镜像内容 docker commit提交修改的 ...

  4. 修改文件MD5值

    1.查看文件的MD5值 (1)下载MD5Checker http://getmd5checker.com/download.html 或者 链接: https://pan.baidu.com/s/1e ...

  5. python 计算器

    import redef main(): #""代表的是空,split()方法已空格或者\t,\n进行切割,join方法是列表,元组,字典变为字符串 a = "" ...

  6. JVM TI

    JVM TI JVM TI全名Java Virtual Machine Tool Interface,是开发虚拟机监控工具使用的编程接口,它可以监控JVM内部时间的执行,也可以控制JVM的某些行为,可 ...

  7. python发送邮件心得体会

    利用本地smtp server发送 windows下尝试装了两个smtp server大概配置了下,发现没法生效,也没时间仔细研究了.装上foxmail发现以前可以本地发送的选项已经无法找到. 不带附 ...

  8. 配置成功java11后安装eclipse失败

    前提是 1.java是成功配置的, 2.看清楚32bit,还是64bit,需要一致 THEN 方法一:去安装java11之前的版本,正确配置环境 方法二:java11中没有jre(不打紧).所以需要直 ...

  9. Openrasp源码分析

    Openrasp是百度关于rasp技术的开源项目,由于工作需要,之前对rasp的源码进行了简单的分析.文章是之前就写好的,现在放出了,希望对大家有写帮助. OpenRASP中java引擎的源码分析 安 ...

  10. wangEditor编辑器 Vue基本配置项

    wangEditor编辑器 Vue基本配置项 1.Vue安装方法 npm i wangeditor -S <template> <div id='wangeditor'> &l ...