码迷,mamicode.com
首页 > 其他好文 > 详细

以前刷过的FFT

时间:2018-08-10 23:04:01      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:i++   regional   scanf   tar   ++i   operator   main   acm   fine   

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\n",ans);
}

 

以前刷过的FFT

标签:i++   regional   scanf   tar   ++i   operator   main   acm   fine   

原文地址:https://www.cnblogs.com/BobHuang/p/9457315.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!