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. SLAM+语音机器人DIY系列:(四)差分底盘设计——5.底盘PID控制参数整定

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  2. 关于PHP打开之后找不到数据库问题的记录

    昨天发现了一个奇怪的问题,一直正常使用的某个网站打不开了,这个网站是PHP写的,数据库用的my sql.打开之后就提示密码错误,无法正常打开页面. 由于平时基本上没用过my sql,按照使用sql s ...

  3. Linux下安装使用Redis

    cd /usr/local/src   //进入src目录  wget http://download.redis.io/releases/redis-4.0.1.tar.gz  //下载到src   ...

  4. Web后端 JAVA学习之路

    1.Java分类 Java按应用来分,可以分为J2ME(手机版),J2SE(标准版),J2EE(企业版)三部分. ・J2ME:已经被安卓开发取代. ・J2SE:Java的核心类,其中包括桌面应用,但一 ...

  5. ArcGIS API for JavaScript 入门教程[7] 再讲视图——View的基本属性

    [回顾]上篇花大篇幅讲了ArcGIS Server上的数据服务与部分常用可操作图层的创建关系,还讲了OGC的几个规范. 本篇回到JsAPI 4.x的新特性——视图类中来. 在第3篇讲过,4.x将视图从 ...

  6. openlayers 3方法继承

    之前Web GIS开发使用的ArcGIS API用起来很系统,但是使用开源Web GIS API已经成主流趋势(你懂的~),最近项目想要从ArcGIS API 转到openlayers API,用起来 ...

  7. Skyline Te Pro二次开发技能总结

    前两天项目开发中,忽然一个Imagelabel的参数不会调了,但是前段时间可是很熟悉的.好吧,好记性不如烂笔头! 1. 模型弹出窗调试 这里的模型弹出框指涉及到模型操作的,比如监听模型选定事件.根据窗 ...

  8. jQueryMobile 網頁使用 ASP.NET Web API 服務

    微軟的 ASP.NET Web API 框架,能以 RESTful 輕量級的架構風格,建立 HTTP 服務,讓多種不同的用戶端,如: 手機.平板.電腦(PC),透過 HTTP 的 GET.POST.P ...

  9. Java导出Excel的Springmvc实例

     @RequestMapping(value = "downloadExcel", method = RequestMethod.GET)  public String downl ...

  10. eclipse下解决明明有jar包,却找不到的问题

    首先右键提示缺失jar包的项目,也可能是缺失maven依赖的项目. 右键选择properties. 选择deployment assembly. 将缺少依赖的jar包,add进去.