以前刷过的FFT
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
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
10 4 1
AGCAATTCAT
ACAT
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的更多相关文章
- 点分治Day1
树套树Day2暂且搁置...因为Day1的题我各种不会做... 唯一过了一道还是整体二分过的... 我们来一点愉快的算法,先不考虑数据结构这种骚东西了 毕竟还在发烧,就先码码这几天在搞的点分治吧 hx ...
- 【刷题】BZOJ 2179 FFT快速傅立叶
Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出 ...
- [暑假的bzoj刷水记录]
(这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊 堆一起算了 隔一段更新一下. 7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...
- 洛谷P1919 【模板】A*B Problem升级版 题解(FFT的第一次实战)
洛谷P1919 [模板]A*B Problem升级版(FFT快速傅里叶) 刚学了FFT,我们来刷一道模板题. 题目描述 给定两个长度为 n 的两个十进制数,求它们的乘积. n<=100000 如 ...
- ZJOI2019一轮停课刷题记录
Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...
- 【BZOJ 3451】Tyvj1953 Normal 思维题+期望概率+FFT+点分治
我感觉是很强的一道题……即使我在刷专题,即使我知道这题是fft+点分治,我仍然做不出来……可能是知道是fft+点分治限制了我的思路???(别做梦了,再怎样也想不出来的……)我做这道题的话,一看就想单独 ...
- 多项式乘法,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 ...
- 洛谷P1919 A*B problem 快速傅里叶变换模板 [FFT]
题目传送门 A*B problem 题目描述 给出两个n位10进制整数x和y,你需要计算x*y. 输入输出格式 输入格式: 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数 ...
- bzoj 4503 两个串 快速傅里叶变换FFT
题目大意: 给定两个\((length \leq 10^5)\)的字符串,问第二个串在第一个串中出现了多少次.并且第二个串中含有单字符通配符. 题解: 首先我们从kmp的角度去考虑 这道题从字符串数据 ...
随机推荐
- 【LeetCode】9 Palindrome Number 回文数判定
题目: Determine whether an integer is a palindrome. Do this without extra space. Some hints: Could neg ...
- 洛谷 P2038 无线网络发射器选址
题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻 ...
- thinkphp 跳转
1 $this -> redirect('index',array('type'=>2,'id'=>0)); //直接跳转 2 $this->success('提交失 ...
- CF Gym 100187M Heaviside Function(二分)
题意:给你一个函数和一些系数,给你一堆询问,求函数值. 根据s的符号,分成两组讨论,函数值与比x小的系数数量有关,二分输出答案. #include<cstdio> #include< ...
- C++11 function用法 可调用对象模板类
std::function<datatype()> ()内写参数类型 datatype 代表function的返回值 灵活的用法.. 代码如下 #include <stdio.h&g ...
- QT+event() + 事件过滤器
其存在的意义: mywidget.h: #ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> namespace Ui { cl ...
- Python——字典dict()详解
一.字典 字典是Python提供的一种数据类型,用于存放有映射关系的数据,字典相当于两组数据,其中一组是key,是关键数据(程序对字典的操作都是基于key),另一组数据是value,可以通过key来进 ...
- java,编写一个从1循环到150并在每行打印一个值,另外在每个3的倍数行上打印出foo,在每个5的倍数行上打印biz,在每个7的倍数上打印baz.
需求:编写一个从1循环到150并在每行打印一个值,另外在每个3的倍数行上打印出foo,在每个5的倍数行上打印biz,在每个7的倍数上打印baz. package study01; public cla ...
- [BZOJ] 1520: [POI2006]Szk-Schools
费用流解决. abs内传不了int..CE一次 #include<iostream> #include<cstring> #include<cstdio> #inc ...
- [提供可行性脚本] RHEL 7/CentOS 7/Fedora28 重命名网卡名称
实验说明: 在许多自动化任务中,脚本往往是通过读取配置文件来获取信息的,红帽系的系统自升级之后(CentOS7/RHEL7),网卡命名采用“一致性网络设备接口”的命名方法,导致不同设备的不同网卡名称各 ...