Gym - 101667H

2017-2018 ACM-ICPC, Asia Daejeon Regional Contest

#include<bits/stdc++.h>
using namespace std;
#define maxn 4000005
const double pi=acos(-1.0);
struct com
{
double x,y;
com(double X=,double Y=)
{
x=X,y=Y;
}
}a[maxn],b[maxn];
com operator + (com a,com b) {return com(a.x+b.x,a.y+b.y);}
com operator - (com a,com b) {return com(a.x-b.x,a.y-b.y);}
com operator * (com a,com b) {return com(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
int S,T,n,m,L,R[maxn],ans[maxn];
long long F[maxn];
char s[maxn],t[maxn];
double f[maxn],g[maxn];
void FFT(com a[maxn],int opt)
{
for (int i=;i<n;++i)
if (i<R[i]) swap(a[i],a[R[i]]);
for (int k=;k<n;k<<=)
{
com wn=com(cos(pi/k),opt*sin(pi/k));
for (int i=;i<n;i+=(k<<))
{
com w=com(,);
for (int j=;j<k;++j,w=w*wn)
{
com x=a[i+j],y=w*a[i+j+k];
a[i+j]=x+y,a[i+j+k]=x-y;
}
}
}
}
void calc(int opt)
{
FFT(a,);FFT(b,);
for (int i=;i<=n;++i) a[i]=a[i]*b[i];
FFT(a,-);
for (int i=S-;i<T;++i)
{
F[i]+=(long long)(a[i].x/n+0.5)*opt;//对于每种匹配位置累计赢的次数
}
}
int main()
{
scanf("%d%d",&T,&S);
scanf("%s%s",t,s);//S短,T长
for(int i=;i<S/;++i) swap(s[i],s[S-i-]);//短串逆置
T=T+S;
for(int i=T-S;i<T;i++)t[i]='B';
t[T]=;
m=S+T-;
for(int i=;i<T;i++)
{
if(t[i]=='S')t[i]='R';
else if(t[i]=='R')t[i]='P';
else if(t[i]=='P')t[i]='S';
}
for (n=;n<=m;n<<=) ++L;
for (int i=;i<n;++i)
R[i]=(R[i>>]>>)|((i&)<<(L-));
for (int i=;i<T;++i) f[i]=(t[i]=='S');
for (int i=;i<S;++i) g[i]=(s[i]=='S');
for (int i=;i<=n;++i) a[i]=com(,),b[i]=com(,);
for (int i=;i<T;++i) a[i].x=f[i];
for (int i=;i<S;++i) b[i].x=g[i];
calc();
for (int i=;i<T;++i) f[i]=(t[i]=='R');
for (int i=;i<S;++i) g[i]=(s[i]=='R');
for (int i=;i<=n;++i) a[i]=com(,),b[i]=com(,);
for (int i=;i<T;++i) a[i].x=f[i];
for (int i=;i<S;++i) b[i].x=g[i];
calc();
for (int i=;i<T;++i) f[i]=(t[i]=='P');
for (int i=;i<S;++i) g[i]=(s[i]=='P');
for (int i=;i<=n;++i) a[i]=com(,),b[i]=com(,);
for (int i=;i<T;++i) a[i].x=f[i];
for (int i=;i<S;++i) b[i].x=g[i];
calc();
long long ans=;
for (int i=S-;i<T;++i)//这个范围自己考虑一下就好了
ans=max(ans,F[i]);//所有位置取max
printf("%lld\n",ans);
}

模仿这个题目在TOJ出了一个题,还无人AC 烟村四五家

Fuzzy Search

 CodeForces - 528D

Leonid works for a small and promising start-up that works on decoding the human genome. His duties include solving complex problems of finding certain patterns in long strings consisting of letters 'A', 'T', 'G' and 'C'.

Let's consider the following scenario. There is a fragment of a human DNA chain, recorded as a string S. To analyze the fragment, you need to find all occurrences of string T in a string S. However, the matter is complicated by the fact that the original chain fragment could contain minor mutations, which, however, complicate the task of finding a fragment. Leonid proposed the following approach to solve this problem.

Let's write down integer k ≥ 0 — the error threshold. We will say that string Toccurs in string S on position i (1 ≤ i ≤ |S| - |T| + 1), if after putting string Talong with this position, each character of string T corresponds to the some character of the same value in string S at the distance of at most k. More formally, for any j (1 ≤ j ≤ |T|) there must exist such p (1 ≤ p ≤ |S|), that |(i + j - 1) - p| ≤ k and S[p] = T[j].

For example, corresponding to the given definition, string "ACAT" occurs in string "AGCAATTCAT" in positions 2, 3 and 6.

Note that at k = 0 the given definition transforms to a simple definition of the occurrence of a string in a string.

Help Leonid by calculating in how many positions the given string T occurs in the given string S with the given error threshold.

Input

The first line contains three integers |S|, |T|, k (1 ≤ |T| ≤ |S| ≤ 200 000, 0 ≤ k ≤ 200 000) — the lengths of strings S and T and the error threshold.

The second line contains string S.

The third line contains string T.

Both strings consist only of uppercase letters 'A', 'T', 'G' and 'C'.

Output

Print a single number — the number of occurrences of T in S with the error threshold k by the given definition.

Examples

Input
10 4 1
AGCAATTCAT
ACAT
Output
3

Note

If you happen to know about the structure of the human genome a little more than the author of the problem, and you are not impressed with Leonid's original approach, do not take everything described above seriously.

#include<bits/stdc++.h>
using namespace std;
typedef double db;
const db PI=acos(-1.0);
struct Complex
{
db x,y;
Complex(db _x=0.0,db _y=0.0):x(_x),y(_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 change(Complex y[],int len)
{
for(int i=,j=len/;i<len-;i++)
{
if(i<j)swap(y[i],y[j]);
int k=len/;
while(j>=k)
{
j-=k;
k/=;
}
if(j<k)j+=k;
}
}
void fft(Complex y[],int len,int on)
{
change(y,len);
for(int h=;h<=len;h<<=)
{
Complex wn(cos(-on**PI/h),sin(-on**PI/h));
for(int j=;j<len;j+=h)
{
Complex w(,);
for(int k=j;k<j+h/;k++)
{
Complex u=y[k];
Complex t=w*y[k+h/];
y[k]=u+t;
y[k+h/]=u-t;
w=w*wn;
}
}
}
if(on==-)
for(int i=;i<len;i++)
y[i].x/=len;
}
const char ch[]={'A','C','G','T'};
int lens,lent,k;
char s[],t[];
int es[],ps[];
Complex ss[],tt[];
int cnt[][];
void work(int id)
{
memset(es,,sizeof(es));
memset(ps,,sizeof(ps));
memset(ss,,sizeof(ss));
memset(tt,,sizeof(tt));
for(int i=;i<lens;i++)
if(s[i]==ch[id])
{
es[max(i-k,)]++;
es[min(i+k+,lens)]--;
}
ps[]=es[];
for(int i=;i<lens;i++)ps[i]=es[i]+ps[i-];
for(int i=;i<lens;i++)ss[i].x=(ps[i]>);
for(int i=;i<lent;i++)tt[i].x=(t[i]==ch[id]);
reverse(tt,tt+lent);
int len=;
while(len<*lens || len<*lent)len<<=;
fft(ss,len,);
fft(tt,len,);
for(int i=;i<len;i++)ss[i]=ss[i]*tt[i];
fft(ss,len,-);
for(int i=;i<lens;i++)cnt[id][i]=(int)(ss[i+lent-].x+0.5);
}
int main()
{
scanf("%d%d%d",&lens,&lent,&k);
scanf("%s%s",s,t);
for(int i=;i<;i++)work(i);
int ans=;
for(int i=;i<lens;i++)
{
int tot=;
for(int j=;j<;j++)tot+=cnt[j][i];
ans+=(tot==lent);
}
printf("%d\n",ans);
return ;
}

以前刷过的FFT的更多相关文章

  1. 点分治Day1

    树套树Day2暂且搁置...因为Day1的题我各种不会做... 唯一过了一道还是整体二分过的... 我们来一点愉快的算法,先不考虑数据结构这种骚东西了 毕竟还在发烧,就先码码这几天在搞的点分治吧 hx ...

  2. 【刷题】BZOJ 2179 FFT快速傅立叶

    Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出 ...

  3. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

  4. 洛谷P1919 【模板】A*B Problem升级版 题解(FFT的第一次实战)

    洛谷P1919 [模板]A*B Problem升级版(FFT快速傅里叶) 刚学了FFT,我们来刷一道模板题. 题目描述 给定两个长度为 n 的两个十进制数,求它们的乘积. n<=100000 如 ...

  5. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

  6. 【BZOJ 3451】Tyvj1953 Normal 思维题+期望概率+FFT+点分治

    我感觉是很强的一道题……即使我在刷专题,即使我知道这题是fft+点分治,我仍然做不出来……可能是知道是fft+点分治限制了我的思路???(别做梦了,再怎样也想不出来的……)我做这道题的话,一看就想单独 ...

  7. 多项式乘法,FFT与NTT

    多项式: 多项式?不会 多项式加法: 同类项系数相加: 多项式乘法: A*B=C $A=a_0x^0+a_1x^1+a_2x^2+...+a_ix^i+...+a_{n-1}x^{n-1}$ $B=b ...

  8. 洛谷P1919 A*B problem 快速傅里叶变换模板 [FFT]

    题目传送门 A*B problem 题目描述 给出两个n位10进制整数x和y,你需要计算x*y. 输入输出格式 输入格式: 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数 ...

  9. bzoj 4503 两个串 快速傅里叶变换FFT

    题目大意: 给定两个\((length \leq 10^5)\)的字符串,问第二个串在第一个串中出现了多少次.并且第二个串中含有单字符通配符. 题解: 首先我们从kmp的角度去考虑 这道题从字符串数据 ...

随机推荐

  1. Java Object Model(一)

    Java作为OOP语言,抽象性不言而喻.如果需要深入了解Java语言的实现机制,则不得不对Java语言中基础的概念有清晰的了解.今天是我在cnblog上写博客的第一天,希望今天的博客可以是我成为未来& ...

  2. javaScript的注释、变量和基本数据类型

    上一级写了javaScript是用来操作文档对象元素的,这一次带大家看看javaScriput的注释.变量和基本数据类型. 1.注释:注释是什么呢?注释其实就是阻止浏览器解析某一行或者多行代码或描述的 ...

  3. jsp另外五大内置对象之-exception

    //有异常的页面 <%@ page language="java" contentType="text/html; charset=utf-8" page ...

  4. [VC]WindowProc和DefWindowProc函数

    在Windows操作系统里,当窗口显示之后,它就可以接收到系统源源不断地发过来的消息,然后窗口就需要处理这些消息,因此就需要一个函数来处理这些消 息.在API里定义了一个函数为回调函数,当系统需要向窗 ...

  5. UVA 1599, POJ 3092 Ideal Path 理想路径 (逆向BFS跑层次图)

    大体思路是从终点反向做一次BFS得到一个层次图,然后从起点开始依次向更小的层跑,跑的时候选则字典序最小的,由于可能有多个满足条件的点,所以要把这层满足条件的点保存起来,在跑下一层.跑完一层就会得到这层 ...

  6. 【转】iOS学习笔记(十七)——文件操作(NSFileManager)

    iOS的沙盒机制,应用只能访问自己应用目录下的文件.iOS不像android,没有SD卡概念,不能直接访问图像.视频等内容.iOS应用产生的内容,如图像.文件.缓存内容等都必须存储在自己的沙盒内.默认 ...

  7. 查看numpy的类型

    查看一个变量的类型:type(img) 查看array中的数据值的类型:img.dtype 查看array的形状:img.shape

  8. GCD之dispatch queue

    GCD之dispatch queue iOS中多线程编程工具主要有: NSThread NSOperation GCD 这三种方法都简单易用,各有千秋.但无疑GCD是最有诱惑力的,因为其本身是appl ...

  9. Codevs3324 新斯诺克

    题目描述 Description 斯诺克又称英式台球,是一种流行的台球运动.在球桌上,台面四角以及两长边中心位置各有一个球洞,使用的球分别为1 个白球,15 个红球和6 个彩球(黄.绿.棕.蓝.粉红. ...

  10. centos7 rpm安装mysql5.7

    1.去官网下载指定的数据库版本:https://dev.mysql.com/downloads/mysql/ 2.根据所用的操作系统下载指定的rpm包 3.下载及安装 地址链接wget https:/ ...