以前刷过的FFT
Posted bobhuang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以前刷过的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=0,double Y=0) { 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=0;i<n;++i) if (i<R[i]) swap(a[i],a[R[i]]); for (int k=1;k<n;k<<=1) { com wn=com(cos(pi/k),opt*sin(pi/k)); for (int i=0;i<n;i+=(k<<1)) { com w=com(1,0); for (int j=0;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,1);FFT(b,1); for (int i=0;i<=n;++i) a[i]=a[i]*b[i]; FFT(a,-1); for (int i=S-1;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=0;i<S/2;++i) swap(s[i],s[S-i-1]);//短串逆置 T=T+S; for(int i=T-S;i<T;i++)t[i]=‘B‘; t[T]=0; m=S+T-2; for(int i=0;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=1;n<=m;n<<=1) ++L; for (int i=0;i<n;++i) R[i]=(R[i>>1]>>1)|((i&1)<<(L-1)); for (int i=0;i<T;++i) f[i]=(t[i]==‘S‘); for (int i=0;i<S;++i) g[i]=(s[i]==‘S‘); for (int i=0;i<=n;++i) a[i]=com(0,0),b[i]=com(0,0); for (int i=0;i<T;++i) a[i].x=f[i]; for (int i=0;i<S;++i) b[i].x=g[i]; calc(1); for (int i=0;i<T;++i) f[i]=(t[i]==‘R‘); for (int i=0;i<S;++i) g[i]=(s[i]==‘R‘); for (int i=0;i<=n;++i) a[i]=com(0,0),b[i]=com(0,0); for (int i=0;i<T;++i) a[i].x=f[i]; for (int i=0;i<S;++i) b[i].x=g[i]; calc(1); for (int i=0;i<T;++i) f[i]=(t[i]==‘P‘); for (int i=0;i<S;++i) g[i]=(s[i]==‘P‘); for (int i=0;i<=n;++i) a[i]=com(0,0),b[i]=com(0,0); for (int i=0;i<T;++i) a[i].x=f[i]; for (int i=0;i<S;++i) b[i].x=g[i]; calc(1); long long ans=0; for (int i=S-1;i<T;++i)//这个范围自己考虑一下就好了 ans=max(ans,F[i]);//所有位置取max printf("%lld ",ans); }
以上是关于以前刷过的FFT的主要内容,如果未能解决你的问题,请参考以下文章
首发爆火!刷了阿里大神写的Spring源码笔记之后,感觉之前刷过的都是渣渣!