1028 大数乘法 V2(NTT or FTT)

给出2个大整数A,B,计算A*B的结果。

输入
第1行:大数A
第2行:大数B
(A,B的长度 <= 100000,A,B >= 0)
输出
输出A * B
输入样例
123456
234567
输出样例
28958703552

纯粹想试一下我弄的NTT的板子的准确性

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
#include<queue>
#include<complex>
#define ll long long
//#define Complex complex<double>
using namespace std;
const double PI=acos(-1.0);
/*struct Complex
{
    double x,y;
    Complex(double _x=0.0,double _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);
    }
};//复数定义*/
const int mod=998244353,g=3;
int P(int a,int b)
{
    int ans=1;
    while(b)
    {
        if(b&1)ans=(ll)ans*a%mod;
        a=(ll)a*a%mod;
        b>>=1;
    }
    return ans;
}
struct NTT
{
    void change(int y[],int len)//len必须是2的幂次
    {
        int i,j,k;
        for(i=1,j=len>>1;i<len-1;i++)
        {
            if(i<j)swap(y[i],y[j]);
            k=len>>1;
            while(j>=k)
            {
                j-=k;
                k/=2;
            }
            if(j<k)j+=k;
        }
    }
    void dft(int y[],int len,int on)//len必须是2的幂次
    {
        change(y,len);
        for(int h=2;h<=len;h<<=1)
        {
            int wn=P(g,on==1?(mod-1)/h:mod-1-(mod-1)/h);
            for(int j=0;j<len;j+=h)
            {
                int w=1;
                for(int k=j;k<j+h/2;k++)
                {
                    int u=y[k];
                    int t=(ll)w*y[k+h/2]%mod;
                    y[k]=(u+t)%mod;
                    y[k+h/2]=(u-t+mod)%mod;
                    w=(ll)w*wn%mod;
                }
            }
        }
        if(on==-1)
        {
            int inv=P(len,mod-2);
            for(int i=0;i<len;i++)
                y[i]=(ll)y[i]*inv%mod;
        }

    }//on为1时是把系数表示转化为点值表示即DFT,为-1时即逆DFT,还原为系数表示
    inline void mul(int x1[],int n1,int x2[],int n2,int res[],int& n)
    {
        n=1;
        int _n=n1+n2-1;
        while(n<_n)n<<=1;//把len填充到2的幂次
        /*for(int i=n1;i<n;i++)
            x1[i]=Complex(0,0);//补位填零
        for(int i=n2;i<n;i++)
            x2[i]=Complex(0,0);//补位填零*/
        dft(x1,n,1);//转化为点值
        dft(x2,n,1);//转化为点值
        for(int i=0;i<n;i++)
            x1[i]=(ll)x1[i]*x2[i]%mod;
        dft(x1,n,-1);//转化为系数
        /*for(int i=0;i<n;i++)
            res[i]=(ll)(x1[i].x+0.5);//补精度*/
        for(int i=0;i<n;i++)res[i]=x1[i];
        for(int i=0;i<n;i++)res[i+1]+=res[i]/10,res[i]%=10;
        //n=n1+n2-1;
        while(res[n-1]==0)n--;
    }
}ntt;
const int maxx=(1<<21)+5;
int x1[maxx],x2[maxx];
int res[maxx];
char c1[100005],c2[100005];
int main()
{
    scanf("%s%s",c1,c2);
    int n1=strlen(c1);
    int n2=strlen(c2);
    for(int i=0;i<n1;i++)x1[n1-1-i]=c1[i]-'0';
    for(int i=0;i<n2;i++)x2[n2-1-i]=c2[i]-'0';
    int n;
    ntt.mul(x1,n1,x2,n2,res,n);
    for(int i=n-1;i>=0;i--)printf("%d",res[i]);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值