以前刷过的FFT

Posted bobhuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以前刷过的FFT相关的知识,希望对你有一定的参考价值。

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=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的主要内容,如果未能解决你的问题,请参考以下文章

致我们曾经刷过的水题

刷过的题 分类汇总

我刷过的LeetCode题目

首发爆火!刷了阿里大神写的Spring源码笔记之后,感觉之前刷过的都是渣渣!

刷了这份“阿里亿级高并发系统设计学习笔记”,你会觉得之前刷过的都是渣渣!

迄今为止见到过的一个超级妙的关于%的计算!!!!!!!