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​\),有

\[\begin{cases}
x\equiv c_1\pmod{m_1}\\
x\equiv c_2\pmod{m_2}\\
x\equiv c_3\pmod{m_3}
\end{cases}
\]

用中国剩余定理合并前两个同余式,得到

\[\begin{cases}
x\equiv c_3\pmod{m_3}\\
x\equiv c_4\pmod{m_1m_2}
\end{cases}
\]

设 \(x=km_1m_2+c_4\),有

\[km_1m_2+c_4\equiv c_3\pmod{m_3}\\
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=(am_3+(c_3-c_4)m_1^{-1}m_2^{-1})m_1m_2+c_4\\
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的更多相关文章

  1. BZOJ1042 HAOI2008硬币购物(任意模数NTT+多项式求逆+生成函数/容斥原理+动态规划)

    第一眼生成函数.四个等比数列形式的多项式相乘,可以化成四个分式.其中分母部分是固定的,可以多项式求逆预处理出来.而分子部分由于项数很少,询问时2^4算一下贡献就好了.这个思路比较直观.只是常数巨大,以 ...

  2. 【模板】任意模数NTT

    题目描述: luogu 题解: 用$fft$水过(什么$ntt$我不知道). 众所周知,$fft$精度低,$ntt$处理范围小. 所以就有了任意模数ntt神奇$fft$! 意思是这样的.比如我要算$F ...

  3. 【知识总结】多项式全家桶(三)(任意模数NTT)

    经过两个月的咕咕,"多项式全家桶" 系列终于迎来了第三期--(雾) 上一篇:[知识总结]多项式全家桶(二)(ln和exp) 先膜拜(伏地膜)大恐龙的博客:任意模数 NTT (在页面 ...

  4. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  5. 任意模数NTT

    任意模数\(NTT\) 众所周知,为了满足单位根的性质,\(NTT\)需要质数模数,而且需要能写成\(a2^{k} + r\)且\(2^k \ge n\) 比较常用的有\(998244353,1004 ...

  6. [洛谷P4245]【模板】任意模数NTT

    题目大意:给你两个多项式$f(x)$和$g(x)$以及一个模数$p(p\leqslant10^9)$,求$f*g\pmod p$ 题解:任意模数$NTT$,最大的数为$p^2\times\max\{n ...

  7. MTT:任意模数NTT

    MTT:任意模数NTT 概述 有时我们用FFT处理的数据很大,而模数可以分解为\(a\cdot 2^k+1\)的形式.次数用FFT精度不够,用NTT又找不到足够大的模数,于是MTT就应运而生了. MT ...

  8. Luogu 4245 【模板】任意模数NTT

    这个题还有一些其他的做法,以后再补,先记一下三模数$NTT$的方法. 发现这个题不取模最大的答案不会超过$10^5 \times 10^9 \times 10^9 = 10^{23}$,也就是说我们可 ...

  9. 洛谷 4245 【模板】任意模数NTT——三模数NTT / 拆系数FFT

    题目:https://www.luogu.org/problemnew/show/P4245 三模数NTT: 大概是用3个模数分别做一遍,用中国剩余定理合并. 前两个合并起来变成一个 long lon ...

随机推荐

  1. .Net Core 根据配置文件动态发布至服务器

    前言 一个软件的开发周期需要经历开发.测试.上线三个基本的阶段,同理我们在开发过程中会需要经常切换不同的运行环境..NetCore可以通过配置文件以及写入系统环境变量来自动识别站点的运行环境,保证了数 ...

  2. WebGL或OpenGL关于模型视图投影变换的设置技巧

    目录 1. 具体实例 2. 解决方案 1) Cube.html 2) Cube.js 3) 运行结果 3. 详细讲解 1) 模型变换 2) 视图变换 3) 投影变换 4) 模型视图投影矩阵 4. 存在 ...

  3. 无限极分类(adjacency list)的三种方式(迭代、递归、引用)

    一般的分类树状结构有两种方式: 一种是adjacency list,也就是是id,parent id这中形式. 另一种是nested set,即左右值的形式. 左右值形式查询起来比较高效,无需递归等, ...

  4. MyDAL - .QueryListAsync() 使用

    索引: 目录索引 一.API 列表 .QueryListAsync() .QueryListAsync<M>() 如: .QueryListAsync<AgentInventoryR ...

  5. MyDAL - .Where() & .And() & .Or() 使用

    索引: 目录索引 一.API 列表 1.Where .Where(Func<M, bool> func) 如: .Where( it => (it.Prop1>=条件1 &am ...

  6. vue(4)—— vue的过滤器,监听属性,生命周期函数,获取DOM元素

    过滤器 vue允许自定义过滤器,我个人认为,过滤器有两种,一种是对数据的清洗过滤,一种是对数据切换的动画过滤 数据切换的动画过滤 这里还是利用前面的动态组件的例子: 这里由于没办法展示动画效果,代码如 ...

  7. Redis中5种数据结构的使用场景

    一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 ...

  8. WPF软件开发系统之五——展会展厅触摸屏企业产品宣传展示系统

    本系统开发背景:上海展会多点触摸大屏(60寸以上)上互动展示. 功能包括:企业背景.产品.合作伙伴.所获荣誉等以图片.文字.视频多媒体的方式呈块状显示,亮点功能为支持多点操作去旋转.缩放.拖拽呈现各种 ...

  9. saiku环境搭建

    说明:搭建saiku环境,BI展示工具. 环境说明: os:windows7 jdk:jdk1.6.0_43 tomcat:apache-tomcat-7.0.62 saiku:saiku-ui-2. ...

  10. [已解决]报错:Required request body is missing

    问题代码: res = requests.post(getXxxxList_url, headers=headers, data={}) 对象网站: angular4 apache 通过验证 (coo ...