python高精度乘法_洛谷P1919--A*B Problem升级版(NTT优化高精度乘法)

题目背景

本题数据已加强,请使用 FFT/NTT,不要再交 Python 代码浪费评测资源。

题目描述

给你两个正整数 a,b,求$ a \times b$.

输入格式

第一行一个正整数,表示 a;

第二行一个正整数,表示 b。

输出格式

输出一行一个整数表示答案。

输入输出样例

输入

114514

1919810

输出

219845122340

说明/提示

【数据范围】

$1\le a,b \le 10^{1000000}$

可能需要一定程度的常数优化。

emmmm,刚开始学FFT/NTT的可能一下子没有反应过来,我们设输入$s$,那么这个数必然能被表示成$s=a_0*10^0+a_1*10^1+a_2*10^2+\cdots $。。。然后就是个愉快的卷积了^_^,只不过要稍微注意一下顺序的问题和边界的处理

以下是AC代码:

/*

实质上就是将一个数变成a_0*10^0+a_1*10+a_2*10^2...然后就可以快乐地卷积了

*/

#include

#include

#include

#include

#include

using namespace std;

#define IOS ios::sync_with_stdio(false);

typedef long long ll;

const int mac=3e6+10;

const int mod=998244353;

ll a[mac],b[mac],rt[5][30];

int r[mac];

string s1,s2;

ll qpow(ll a,ll b)

{

ll ans=1;

a%=mod;

while (b){

if (b&1) ans=ans*a%mod;

a=a*a%mod;

b>>=1;

}

return ans%mod;

}

void NTT(int len,ll *a,int type)

{

for (int i=0; i

if (i

int nb=1;

for (int mid=1; mid

//ll wn=qpow(G,(mod-1)/(mid<<1));//原根代替单位根

//if (type==-1) wn=qpow(wn,mod-2);//逆变换要乘上逆元

ll wn=rt[type+1][nb++];

for (int j=0; j

ll w=1;

for (int k=0; k

ll x=a[j+k],y=w*a[j+k+mid]%mod;

a[j+k]=(x+y)%mod;

a[j+k+mid]=(x-y+mod)%mod;

}

}

}

}

int main(int argc, char const *argv[])

{

for (int i=0; i<=25; i++){//预处理出每个长度下的逆元

int len=1<

rt[2][i]=qpow(3,(mod-1)/len);//正变换

rt[0][i]=qpow(rt[2][i],mod-2);//逆变换

}

IOS;

cin.tie(0); cout.tie(0);

cin>>s1>>s2;

int len1=s1.length(),len2=s2.length();

for (int i=0; i

a[i]=s1[len1-i-1]-'0';

for (int i=0; i

b[i]=s2[len2-i-1]-'0';

int len=1,l=0;

while (len<=len1+len2) len<<=1,l++;

for (int i=0; i

r[i]=(r[i>>1]>>1)|((i&1)<

NTT(len,a,1); NTT(len,b,1);

for (int i=0; i

a[i]=(a[i]*b[i])%mod;

NTT(len,a,-1);

ll inv=qpow(len,mod-2);

for (int i=0; i<=len1+len2; i++)

a[i]=a[i]*inv%mod;

for (int i=0; i

if (a[i]>=10) {a[i+1]+=a[i]/10; a[i]%=10;}

}

int tail=len1+len2;

while (a[tail]==0 && tail>0) tail--;

while (a[tail]>=10) {a[tail+1]+=a[tail]/10; a[tail++]%=10;}

for (int i=tail; i>=0; i--)

printf("%d",a[i]);

printf("\n");

return 0;

}

标签:P1919,洛谷,10,--,ll,int,tail,include,mod

来源: https://www.cnblogs.com/lonely-wind-/p/13334058.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值