【codeforces 528D】 Fuzzy Search
http://codeforces.com/problemset/problem/528/D (题目链接)
题意
给定母串和模式串,字符集大小为${4}$,给定${k}$,模式串在某个位置匹配当且仅当任意位置模式串的这个字符所对应的母串的位置的左右${k}$个字符之内有一个与它相同的,求匹配次数。
Solution
毛爷爷论文题。我们将${4}$种不同的字符分开计算贡献。每一次计算,先预处理出母串种的每个位置能否匹配,对于每个能够匹配的位置,我们将它赋为${1}$,不能匹配则赋为${0}$,将其存放在数组${A}$中。对于模式串,如果它这一位等于当前计算的这个字符,就将这一位赋为${1}$,否则赋为${0}$,将其存放在数组${B}$中。这样的话,我们将模式串倒过来,那么最后对于这个字符来说,模式串位于某一位置与主串的匹配字符数量就是${A}$和${B}$的卷积。那么最后将所有${4}$种字符的贡献算完,如果某一位置的卷积等于模式串长度,那么久意味着模式串处于这一位置的时候可以与主串匹配。于是我们就可以用${FFT}$来解决这个问题了。
细节
${FFT}$最后统计的时候要转成${LL}$而不是${int}$。
代码
// codeforces 528D
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<complex>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 2147483640
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; typedef complex<double> E;
const int maxn=800010;
int n,m,N,M,K,L;
int ans[maxn],rev[maxn],id[maxn],cnt[5],vis[maxn][5];
char a[maxn],b[maxn];
E A[maxn],B[maxn]; void FFT(E *a,int f) {
for (int i=0;i<N;i++) if (rev[i]>i) swap(a[i],a[rev[i]]);
for (int i=1;i<N;i<<=1) {
E wn(cos(Pi/i),sin(Pi/i));
for (int p=i<<1,j=0;j<N;j+=p) {
E w(1,0);
for (int k=0;k<i;k++,w*=wn) {
E x=a[k+j],y=w*a[k+j+i];
a[k+j]=x+y;a[k+j+i]=x-y;
}
}
}
if (f==-1) reverse(a+1,a+N);
}
int main() {
scanf("%d%d%d",&n,&m,&K);
scanf("%s%s",a+1,b+1);
id['A']=1;id['T']=2;id['G']=3;id['C']=4;
for (int l=0,r=0,i=1;i<=n;i++) { //get了一个比较美观的写法
while (l<n && l<i-K) cnt[id[(int)a[l++]]]--;
while (r<n && r<i+K) cnt[id[(int)a[++r]]]++;
for (int j=1;j<=4;j++) if (cnt[j]) vis[i][j]=1;
}
M=n+m;
for (N=1;N<=M;N<<=1) L++;
for (int i=0;i<N;i++) rev[i]=(rev[i>>1]>>1) | ((i&1)<<(L-1));
for (int k=1;k<=4;k++) {
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
for (int i=1;i<=n;i++) {
if (vis[i][k]) A[i-1]=1;
else A[i-1]=0;
}
for (int i=1;i<=m;i++) {
if (id[(int)b[i]]==k) B[m-i]=1;
else B[m-i]=0;
}
FFT(A,1);FFT(B,1);
for (int i=0;i<N;i++) A[i]*=B[i];
FFT(A,-1);
for (int i=0;i<N;i++) ans[i]+=(LL)(A[i].real()+0.5)/N; //此处LL
}
int res=0;
for (int i=0;i<N;i++) if (ans[i]==m) res++;
printf("%d",res);
return 0;
}
【codeforces 528D】 Fuzzy Search的更多相关文章
- 【CF528D】Fuzzy Search(FFT)
[CF528D]Fuzzy Search(FFT) 题面 给定两个只含有\(A,T,G,C\)的\(DNA\)序列 定义一个字符\(c\)可以被匹配为:它对齐的字符,在距离\(K\)以内,存在一个字符 ...
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【Codeforces528D】Fuzzy Search FFT
D. Fuzzy Search time limit per test:3 seconds memory limit per test:256 megabytes input:standard inp ...
- 【codeforces 707E】Garlands
[题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...
- 【codeforces 707C】Pythagorean Triples
[题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...
- 【codeforces 709D】Recover the String
[题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...
- 【codeforces 709B】Checkpoints
[题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...
- 【codeforces 709C】Letters Cyclic Shift
[题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...
- 【Codeforces 429D】 Tricky Function
[题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...
随机推荐
- 基于C#的机器学习--贝叶斯定理-执行数据分析解决肇事逃逸之谜
贝叶斯定理-执行数据分析解决肇事逃逸之谜 在这一章中,我们将: 应用著名的贝叶斯定理来解决计算机科学中的一个非常著名的问题. 向您展示如何使用贝叶斯定理和朴素贝叶斯来绘制数据,从真值表中发现异常值 ...
- XSS(Cross Site Script)
类型一:反射型XSS 简单地把用户输入的数据“反射”给浏览器.也就是说,黑客需要诱使用户“点击”一个恶意链接,才能攻击成功. 类型二:存储型XSS 把用户输入的数据“存储”在服务器端.这种XSS具有很 ...
- 6.openldap客户端安装
作者:yaoyao 1.账号登录系统流程讲解 当在客户端输入账号登录系统时.系统根据/etc/nsswitch.conf配置文件获取账号查找顺序,然后在根据pam配置文件调用相关模块,对账号/etc/ ...
- pstree命令详解
基础命令学习目录首页 pstree命令是用于查看进程树之间的关系,即哪个进程是父进程,哪个是子进程,可以清楚的看出来是谁创建了谁#pstree几个重要的参数:-A: 各进程树之间的连接以ASCII码字 ...
- Python基础系列讲解—动态类型语言的特点
前言 在C语言中变量所分配到的地址是内存空间中一个固定的位置,当我们改变变量值时, 对应内存空间中的值也相应改变.在Python中变量存储的机制是完全不一样的,当给一个变量赋值时首先解释器会给这个值分 ...
- 12_Java面向对象_第12天(构造方法、this、super)_讲义
今日内容介绍 1.构造方法 2.this关键字 3.super关键字 4.综合案例 01构造方法引入 A:构造方法的引入 在开发中经常需要在创建对象的同时明确对象的属性值, 比如员工入职公司就要明确他 ...
- maven导入项目时出现“Cannot read lifecycle mapping metadata …… invalid END header (bad central directory offset)pom”错误的解决方法
出现该错误是因为jar包版本不匹配,比如linux上的jar包导入到windows上了.可以将.m2\repository的org.apache.maven.plugins删掉然后让maven重新下载 ...
- js如何判断一个值是不是Array类型
本来判断一个对象类型用typeof是最好的,不过对于Array类型是不适用的可以使用 instanceof操作符var arrayStr=new Array("1","2 ...
- Android开发中常见的内存泄露案例以及解决方法总结
1.单例模式引起的内存泄露 由于单例模式的静态特性,使得它的生命周期和我们的应用一样长,如果让单例无限制的持有Activity的强引用就会导致内存泄漏如错误代码示例: public class Use ...
- 用虚拟机安装了一台Linux系统,突然想克隆一台服务器,克隆后发现无法上网,如何解决?
用虚拟机安装了一台Linux系统,突然想克隆一台服务器,克隆后发现无法上网,如何解决? 答: a.编辑网卡配置文件/etc/sysconfig/network-scripts/ifcfg-eth ...