NTT任意模数模板(+O(1)快速乘)

博客介绍了如何使用NTT(数论变换)在模数较大的情况下进行快速卷积,通过选取三个大于10^24的质数模数进行计算,利用中国剩余定理得到最终答案。同时,讨论了处理超过long long范围的乘法和模运算的O(1)技巧,包括利用模运算公式避免长整数溢出问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NTT任意模数的方法其实有点取巧。

两个数列每个有n个数,每个数的大小最多是10^9。

如果没有模数,那么卷积过后每个位置的答案一定小于10^9*10^9*n,差不多是10^24左右

那么就有一个神奇的做法,选3个乘积大于10^24的NTT模数,分别做一次,得到每个位上模意义下的答案,

然后用中国剩余定理得到模上三个质数乘积的答案。

因为答案显然小于三个质数乘积,那么模上三个质数乘积的答案就是这个数应该的值。

不过这个值可能会超long long(及时不超,对于乘积大于long long的三个质数做中国剩余定理也不是一件小事)

考虑先将两个模数意义下的答案合并,

现在我们还剩两个模数,一个为long long,一个为int

不能中国剩余定理硬上了。

设模数为P1(longlong) ,P2(int), 余数为a1,a2

设答案ANS=P1*K+a1=P2*Q+a2

那么K*P1=P2*Q+(a2-a1)

K*P1 % P2=a2-a1

a1-a2为常数

用同余方程的解法即可解出K模P2(int)意义下的值

又有ANS<P1*P2(之前已证)

so K*P1+a1<P1*P2

显然K<P2

所以原本答案K的值只能为模P2意义下的值

所以我们就求出K了,然后可以不用高精度就算出ANS%MOD(MOD为任意模数)

但是,

回顾整个过程,附加条件非常多。。。。。。

首先每个数<=10^9(再大或许可以通过增加模数的方法解决,但是CRT时可就不能回避高精度取模了,常数捉急)

然后K的值必须为非负.(如果为负数那么就有两个可能的答案了,这是你用第一条性质怎样都无法回避的)

其次你需要解决两个long long相乘mod long long

用二分乘法会T(常数啊),可以用接近作弊的O(1)long long乘法取模:

/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值