CF 528D. Fuzzy Search NTT
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的更多相关文章
- codeforces 528D Fuzzy Search
链接:http://codeforces.com/problemset/problem/528/D 正解:$FFT$. 很多字符串匹配的问题都可以用$FFT$来实现. 这道题是要求在左边和右边$k$个 ...
- CodeForces 528D Fuzzy Search 多项式 FFT
原文链接http://www.cnblogs.com/zhouzhendong/p/8782849.html 题目传送门 - CodeForces 528D 题意 给你两个串$A,B(|A|\geq| ...
- Codeforces 528D Fuzzy Search(FFT)
题目 Source http://codeforces.com/problemset/problem/528/D Description Leonid works for a small and pr ...
- ●codeforces 528D Fuzzy Search
题链: http://codeforces.com/problemset/problem/528/D 题解: FFT 先解释一下题意: 给出两个字符串(只含'A','T','C','G'四种字符),一 ...
- 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]\)中有 ...
- 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, ...
- CodeForces - 528D Fuzzy Search (FFT求子串匹配)
题意:求母串中可以匹配模式串的子串的个数,但是每一位i的字符可以左右偏移k个位置. 分析:类似于 UVALive -4671. 用FFT求出每个字符成功匹配的个数.因为字符可以偏移k个单位,先用尺取法 ...
- CF528D. Fuzzy Search [FFT]
CF528D. Fuzzy Search 题意:DNA序列,在母串s中匹配模式串t,对于s中每个位置i,只要s[i-k]到s[i+k]中有c就认为匹配了c.求有多少个位置匹配了t 预处理\(f[i][ ...
- 【Codeforces528D】Fuzzy Search FFT
D. Fuzzy Search time limit per test:3 seconds memory limit per test:256 megabytes input:standard inp ...
随机推荐
- VUE-008-通过路由 router.push 传递 query 参数(路由 path 识别,请求链接显示参数传递)
在前端页面表单列表修改时,经常需要在页面切换的时候,传递需要修改的表单内容,通常可通过路由进行表单参数的传递. 首先,配置页面跳转路由.在 router/index.js 中配置相应的页面跳转路由,如 ...
- anaconda安装tensorflow报错 No module named 'tensorflow'解决方法(windows)
这个错误的原因可能是,anaconda安装的python版本为3.7,现在tensorflow仅支持python 3.6 改变python版本:首先在命令行创建一个名为python36的环境,指定 ...
- Port Channel and VPC
1.Port Channel 介绍 Port Channel 简介 绑定多个物理链路(最多8条),到一个单一的逻辑链路,在两个物理设备之间 每个物理端口只能被放入一个port-channel中. 在 ...
- mysql--实现oracle的row_number() over功能
有时候我们想要得到每个分组的前几条记录,这个时候oracle中row_number函数使用非常方便,但可惜mysql没有.网上搜了些实现方法. 表flow_task有phaseno(序列号),obje ...
- 创建vs离线安装程序(不联网安装vs)
https://blog.csdn.net/u013064585/article/details/80996933
- FB面经prepare: 3 Window Max Sum
Given a num array, find a window of size k, that has a maximum sum of the k entries. follow-up: Find ...
- Git 撤销到某个版本的代码
Git checkout 版本号 文件名带路径的
- 统计Oracle一个表空间中各个segment占用的空间大小
SQL语句参考以下: select owner,segment_name,segment_type,tablespace_name,sum(bytes)/1024/1024/1024 from dba ...
- [virtualbox] win10与centos共享目录下,nginx访问问题
原文,http://blog.csdn.net/zhezhebie/article/details/73554872 virtualbox自动挂载之后,默认是挂载在/media/sf_WWW下面的: ...
- 大兄dei,早点看清this吧
说道this,可以说是前端中很重要的问题之一了,也是面试或者笔试常考的问题.所以还是早点看清this吧,大兄dei. this是什么?为什么要存在? this关键字是js中最最复杂的机制之一.他被自动 ...