[Luogu 4245] 任意模数NTT
Description
给定 \(2\) 个多项式 \(F(x), G(x)\),请求出 \(F(x) * G(x)\)。
系数对 \(p\) 取模,且不保证 \(p\) 可以分解成 \(p = a \cdot 2^k + 1\) 之形式。
Solution
设 \(m_1=469762049,m_2=998244353,m_3=1004535809\),有
x\equiv c_1\pmod{m_1}\\
x\equiv c_2\pmod{m_2}\\
x\equiv c_3\pmod{m_3}
\end{cases}
\]
用中国剩余定理合并前两个同余式,得到
x\equiv c_3\pmod{m_3}\\
x\equiv c_4\pmod{m_1m_2}
\end{cases}
\]
设 \(x=km_1m_2+c_4\),有
k\equiv (c_3-c_4)m_1^{-1}m_2^{-1}\pmod{m_3}
\]
设 \(k=am_3+(c_3-c_4)m_1^{-1}m_2^{-1}\),有
x\equiv (c_3-c_4)m_1^{-1}m_2^{-1}m_1m_2+c_4\pmod{m_1m_2m_3}
\]
其中 \(m_1^{-1}m_2^{-1}\) 是在模 \(m_3\) 意义下的。
注意 \(exgcd\) 的返回值可能是负数,要处理一下;在 \(ksm(a, b, p)\) 之前先将 \(a\) 对 \(p\) 取模。
Code
#include <cstdio>
#include <algorithm>
typedef long long LL; const int N = 262150;
int a[N], b[N], n, m, nn, mm, pp, R[N], L, p[N], g[N]; LL f[2][N];
int read() {
int x = 0; char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x;
}
void exgcd(LL a, LL b, LL &x, LL &y) {
if (!b) { x = 1, y = 0; return; }
exgcd(b, a % b, y, x), y -= a / b * x;
}
LL ksm(LL a, LL b, LL p) {
LL res = 1;
for (; b; b >>= 1, a = 1LL * a * a % p)
if (b & 1) res = 1LL * res * a % p;
return res;
}
LL mul(LL a, LL b, LL p) {
LL res = 0; int f = 1;
if (a < 0) a = -a, f = -f; if (a >= p) a %= p;
if (b < 0) b = -b, f = -f; if (b >= p) b %= p;
for (; b; b >>= 1, a += a + a < p ? a : a - p)
if ((b & 1) && (res += a) >= p) res -= p;
return res * f;
}
void NTT(LL *A, int f, int t) {
for (int i = 0; i < n; ++i) if (i < R[i]) std::swap(A[i], A[R[i]]);
for (int i = 1; i < n; i <<= 1) {
int wn = ksm(f ? 3 : g[t], (p[t] - 1) / (i << 1), p[t]);
for (int j = 0, r = i << 1; j < n; j += r) {
int w = 1;
for (int k = 0; k < i; ++k, w = 1LL * w * wn % p[t]) {
int x = A[j + k], y = 1LL * w * A[i + j + k] % p[t];
A[j + k] = (x + y) % p[t], A[i + j + k] = (x - y + p[t]) % p[t];
}
}
}
}
void solve(int t, int k) {
LL c[N] = {}, d[N] = {};
for (int i = 0; i <= nn; ++i) c[i] = a[i];
for (int i = 0; i <= mm; ++i) d[i] = b[i];
NTT(c, 1, t), NTT(d, 1, t);
for (int i = 0; i < n; ++i) f[k][i] = 1LL * c[i] * d[i] % p[t];
NTT(f[k], 0, t);
int inv = ksm(n, p[t] - 2, p[t]);
for (int i = 0; i <= m; ++i) f[k][i] = 1LL * f[k][i] * inv % p[t];
}
int main() {
nn = read(), mm = read(), pp = read();
for (int i = 0; i <= nn; ++i) a[i] = read();
for (int i = 0; i <= mm; ++i) b[i] = read();
m = nn + mm; 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));
p[1] = 469762049, p[2] = 998244353, p[3] = 1004535809;
g[1] = 156587350, g[2] = 332748118, g[3] = 334845270;
solve(1, 0), solve(2, 1);
LL mod = 1LL * p[1] * p[2], x, y;
exgcd(p[1], p[2], x, y), x = (x % mod + mod) % mod;
for (int i = 0; i <= m; ++i) f[0][i] = (f[0][i] + mul(mul(x, f[1][i] - f[0][i] + mod, mod), p[1], mod)) % mod;
solve(3, 1);
LL inv = ksm(mod % p[3], p[3] - 2, p[3]);
for (int i = 0; i <= m; ++i) printf("%lld ", (mul(((f[1][i] - f[0][i]) % p[3] + p[3]) * inv % p[3], mod, pp) + f[0][i]) % pp);
return 0;
}
[Luogu 4245] 任意模数NTT的更多相关文章
- BZOJ1042 HAOI2008硬币购物(任意模数NTT+多项式求逆+生成函数/容斥原理+动态规划)
第一眼生成函数.四个等比数列形式的多项式相乘,可以化成四个分式.其中分母部分是固定的,可以多项式求逆预处理出来.而分子部分由于项数很少,询问时2^4算一下贡献就好了.这个思路比较直观.只是常数巨大,以 ...
- 【模板】任意模数NTT
题目描述: luogu 题解: 用$fft$水过(什么$ntt$我不知道). 众所周知,$fft$精度低,$ntt$处理范围小. 所以就有了任意模数ntt神奇$fft$! 意思是这样的.比如我要算$F ...
- 【知识总结】多项式全家桶(三)(任意模数NTT)
经过两个月的咕咕,"多项式全家桶" 系列终于迎来了第三期--(雾) 上一篇:[知识总结]多项式全家桶(二)(ln和exp) 先膜拜(伏地膜)大恐龙的博客:任意模数 NTT (在页面 ...
- 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)
再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...
- 任意模数NTT
任意模数\(NTT\) 众所周知,为了满足单位根的性质,\(NTT\)需要质数模数,而且需要能写成\(a2^{k} + r\)且\(2^k \ge n\) 比较常用的有\(998244353,1004 ...
- [洛谷P4245]【模板】任意模数NTT
题目大意:给你两个多项式$f(x)$和$g(x)$以及一个模数$p(p\leqslant10^9)$,求$f*g\pmod p$ 题解:任意模数$NTT$,最大的数为$p^2\times\max\{n ...
- MTT:任意模数NTT
MTT:任意模数NTT 概述 有时我们用FFT处理的数据很大,而模数可以分解为\(a\cdot 2^k+1\)的形式.次数用FFT精度不够,用NTT又找不到足够大的模数,于是MTT就应运而生了. MT ...
- Luogu 4245 【模板】任意模数NTT
这个题还有一些其他的做法,以后再补,先记一下三模数$NTT$的方法. 发现这个题不取模最大的答案不会超过$10^5 \times 10^9 \times 10^9 = 10^{23}$,也就是说我们可 ...
- 洛谷 4245 【模板】任意模数NTT——三模数NTT / 拆系数FFT
题目:https://www.luogu.org/problemnew/show/P4245 三模数NTT: 大概是用3个模数分别做一遍,用中国剩余定理合并. 前两个合并起来变成一个 long lon ...
随机推荐
- [转] 以后再有人问你selenium是什么,你就把这篇文章给他
本文转自:https://blog.csdn.net/TestingGDR/article/details/81950593 写在最前面:目前自动化测试并不属于新鲜的事物,或者说自动化测试的各种方法论 ...
- FSLIB.NETWORK 简易使用指南
1.介绍 FSLIB.NETWORK 是一款开源HTTP的高性能高易用性网络库,是对HttpWebRequest/HttpWebResponse的包装,目的是为了用起来更简单明了.设计的时候就为了提供 ...
- 第二次上机,ASP内置对象的使用
3.新建Reg.asp文档,参照1中的Reg.html,通过VBScript服务器端脚本代码实现 ”班级” Select表单的自动生成,如下所示: 注:通过循环语句,采用Response.Write命 ...
- Web API 持续集成:PostMan+Newman+Jenkins(图文讲解)
本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 上篇文章我们已经完成了API测试工具选型,接下来是一系列周期性的开发 ...
- springboot模块
1.web <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s ...
- 详细QRCode生成二维码和下载实现案例
using System; using System.Collections.Generic; using System.Linq; using System.Web; using ThoughtWo ...
- windows下编译Grafana前端
本次介绍一下Windows环境源码编译步骤. 准备 安装Go 1.8.1 安装NodeJS LTS 安装Git 安装golang开发环境: 参考链接:https://www.cnblogs.com/ ...
- springboot整合shiro应用
1.Shiro是Apache下的一个开源项目,我们称之为Apache Shiro.它是一个很易用与Java项目的的安全框架,提供了认证.授权.加密.会话管理,与spring Security 一样都是 ...
- mstsc远程连接发生身份验证错误要求的函数不受支持
在win7电脑上使用远程连接连接一台服务器时,出现发生身份验证错误要求的函数不受支持的错误,原因是本地组策略配置错误,如下图: 解决办法: 进入windows命令行模式输入命令: 会弹出本地策略组编辑 ...
- 【博客导航】Nico博客导航汇总
摘要 介绍本博客关注的内容大类.任务.工具方法及链接,提供Nico博文导航. 导航汇总 [博客导航]Nico博客导航汇总 [导航]信息检索导航 [导航]Python相关 [导航]读书导航 [导航]FP ...