bzoj2179 FFT快速傅立叶

来源:互联网 发布:自动装修软件 编辑:程序博客网 时间:2024/05/01 02:50

NTT。

#include<cstdio>#include<algorithm>using namespace std;#define LL long longconst int p=998244353,maxn=300010;char s1[maxn],s2[maxn];int a[maxn],b[maxn],pow[maxn],rev[maxn],n,l,t;int inc(int x,int y){    x+=y;    return x>=p?x-p:x;}int dec(int x,int y){    x-=y;    return x<0?x+p:x;}void ntt(int *a,int flag){    int x,t1,t2;    for (int i=0;i<l;i++)        if (rev[i]>i) swap(a[i],a[rev[i]]);    for (int i=1;i<=t;i++)        for (int j=0;j<l;j+=1<<i)        {            x=0;            for (int k=j;k<j+(1<<i-1);k++)            {                t1=a[k];                t2=(LL)a[k+(1<<i-1)]*pow[x]%p;                a[k]=inc(t1,t2);                a[k+(1<<i-1)]=dec(t1,t2);                x+=flag*(1<<t-i);                if (x<0) x+=l;            }        }}int main(){    int inv,u;    scanf("%d%s%s",&n,s1+1,s2+1);    for (int i=0;i<n;i++)    {        a[i]=s1[n-i]-'0';        b[i]=s2[n-i]-'0';    }    l=1,t=0;    while (l<n*2-1)    {        t++;        l<<=1;    }    pow[0]=pow[1]=1;    for (int k=(p-1)/l,base=3;k;k>>=1,base=(LL)base*base%p)        if (k&1) pow[1]=(LL)pow[1]*base%p;    for (int i=2;i<l;i++) pow[i]=(LL)pow[i-1]*pow[1]%p;    for (int i=0;i<l;i++)        for (int j=0;j<t;j++)            rev[i]|=((i>>j)&1)<<t-j-1;    ntt(a,1);    ntt(b,1);    for (int i=0;i<l;i++) a[i]=(LL)a[i]*b[i]%p;    ntt(a,-1);    inv=1;    for (int k=p-2,base=l;k;k>>=1,base=(LL)base*base%p)        if (k&1) inv=(LL)inv*base%p;    for (int i=0;i<l;i++) a[i]=(LL)a[i]*inv%p;    for (int i=0;i<l;i++)    {        a[i+1]+=a[i]/10;        a[i]%=10;    }    if (a[l])    {        u=l;        while (a[u])        {            a[u+1]=a[u]/10;            a[u]%=10;            u++;        }        u--;    }    else    {        u=l-1;        while (u&&!a[u]) u--;    }    for (int i=u;i>=0;i--) printf("%d",a[i]);}
原创粉丝点击