任意模数NTT(MTT)模板

记住代码里3个模数,它们的原根都是3.考虑通过3个模数下的答案用中国剩余定理乱搞,得出答案。常数较大。有个什么拆系数FFT不会。

P4245 【模板】任意模数NTT

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rint register int
const int mod[3]={469762049,998244353,1004535809};
const int N=400010;
int n,m,p,l,lim,rev[N],a[3][N],b[3][N];
inline int rd(){
   int x=0,f=1;
   char ch=getchar();
   while(!isdigit(ch)){if(ch==‘-‘)f=-1;ch=getchar();}
   while(isdigit(ch)) x=x*10+(ch^48),ch=getchar();
   return x*f;
}
LL qpow(LL n,LL k,LL P) {
	LL res=1;n%=P;
	while(k) {
		if(k&1)res=res*n%P;
		n=n*n%P;k>>=1;
	}
	return res;
}
inline void MTT(int *a,int P,int g) {
	for(rint i=0;i<lim;++i)
		if(i>rev[i])swap(a[i],a[rev[i]]);
	for(rint i=1;i<lim;i<<=1) {
		int wn=qpow(g,(P-1)/(i<<1),P);
		for(rint j=0;j<lim;j+=(i<<1)) {
			int w0=1;
			for(rint k=0;k<i;++k,w0=1ll*w0*wn%P) {
				int X=a[j+k],Y=1ll*w0*a[i+j+k]%P;
				a[j+k]=(X+Y)%P;
				a[i+j+k]=(X-Y+P)%P;
			}
		}
	}
}
LL get(int i) {
	LL x=a[0][i]+(a[1][i]-a[0][i]+mod[1])*qpow(mod[0],mod[1]-2,mod[1])%mod[1]*mod[0];
	LL y=(x%p+(a[2][i]-x%mod[2]+mod[2])*qpow(1ll*mod[0]*mod[1]%mod[2],mod[2]-2,mod[2])%mod[2]*mod[0]%p*mod[1]%p)%p;
	return y;
}
signed main() {
	n=rd(),m=rd(),p=rd();
	for(rint i=0;i<=n;++i)a[0][i]=a[1][i]=a[2][i]=rd()%p;
	for(rint i=0;i<=m;++i)b[0][i]=b[1][i]=b[2][i]=rd()%p;
	lim=1;while(lim<=n+m)lim<<=1,++l;
	for(rint i=0;i<lim;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
	for(rint i=0;i<3;++i)MTT(a[i],mod[i],3);
	for(rint i=0;i<3;++i)MTT(b[i],mod[i],3);
	for(rint i=0;i<3;++i)
		for(rint j=0;j<lim;++j)
			a[i][j]=1ll*a[i][j]*b[i][j]%mod[i];
	for(rint i=0;i<3;++i)MTT(a[i],mod[i],qpow(3,mod[i]-2,mod[i]));
	for(rint i=0;i<3;++i) {
		int inv=qpow(lim,mod[i]-2,mod[i]);
		for(rint j=0;j<lim;++j)
			a[i][j]=1ll*a[i][j]*inv%mod[i];
	}
	for(rint i=0;i<=n+m;++i)printf("%lld%c",get(i)," \n"[i==n+m]);
	return 0;
}

原文地址:https://www.cnblogs.com/zzctommy/p/12547723.html

时间: 2024-10-07 21:32:29

任意模数NTT(MTT)模板的相关文章

luogu P4245 【模板】任意模数NTT MTT

Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define maxn 1000000 #define M 32768 #define double long double #define ll long long using namespace std; namespace poly{ const double pi=acos(-1); int rev[

MTT:任意模数NTT

MTT:任意模数NTT 概述 有时我们用FFT处理的数据很大,而模数可以分解为\(a\cdot 2^k+1\)的形式.次数用FFT精度不够,用NTT又找不到足够大的模数,于是MTT就应运而生了. MTT没有模数的限制,比NTT更加自由,应用广泛,可以用于任意模数或很大的数. MTT MTT是基于NTT的,其思想很简单,就是做多次NTT,每次使用不同的素数,然后使用CRT合并解,在合并的过程中模最终模数,或是对于无模数的情况使用高精度. 做NTT的次数取决于最大可能答案的大小,所用的所有素数之积必

洛谷P4245 【模板】MTT(任意模数NTT)

题目背景 模板题,无背景 题目描述 给定 22 个多项式 F(x), G(x)F(x),G(x) ,请求出 F(x) * G(x)F(x)∗G(x) . 系数对 pp 取模,且不保证 pp 可以分解成 p = a \cdot 2^k + 1p=a⋅2k+1 之形式. 输入输出格式 输入格式: 输入共 33 行.第一行 33 个整数 n, m, pn,m,p ,分别表示 F(x), G(x)F(x),G(x) 的次数以及模数 pp .第二行为 n+1n+1 个整数, 第 ii 个整数 a_iai?

[题解] Luogu P4245 [模板]任意模数NTT

三模NTT 不会... 都0202年了,还有人写三模NTT啊... 讲一个好写点的做法吧: 首先取一个阀值\(w\),然后把多项式的每个系数写成\(aw + c(c < w)\)的形式,换句话说把多项式\(f(x)\)写成两个多项式相加的形式: \[ f(x) = wf_0(x) + f_1(x) \] 这样在这道题中取\(W = 2^{15}\)就可以避免爆long long了. 乘起来的话就是 \[ f \cdot g = (w f_0 + f_1)(wg_0 + g_1) = (f_0 g

zoj 1081 Points Within 判断点是否在任意多边形内(模板)

题目来源: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=81 分析: 从p点出发做平行于x轴的射线 l. 求射线与 多边形 线段的交点数num, 若是偶数 , 该点 在外, 若为奇数, 该点在内. 注意: 两个特判, 1:   一个是 射线 l 与 多边形的边  重合 , 若该p点在 线段上, 返回1, 否则 交点 记为 0 个 2: 一个是 射线与 线段的交点 ,为线段的端点, 则我们 对线段的 较低交点 不计算. 代码

【51nod】1123 X^A Mod B (任意模数的K次剩余)

题解 K次剩余终极版!orz 写一下,WA一年,bug不花一分钱 在很久以前,我还认为,数论是一个重在思维,代码很短的东西 后来...我学了BSGS,学了EXBSGS,学了模质数的K次剩余--代码一个比一个长-- 直到今天,我写了240行的数论代码,我才发现数论这个东西= =太可怕了 好吧那么我们来说一下任意模数的K次剩余怎么搞 首先,如果模数是奇数,我们可以拆成很多个质数的指数幂,再用解同余方程的方法一个个合起来,细节之后探讨 但是如果,模数有偶数呢 因为要输出所有解,解的个数不多,我们可以倍

三模数NTT模板

求两个多项式的卷积对任意数p取模 两个好记的FNT模数: 5*2^25+1 7*2^26+1 原根都为3 1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include&

任意模数fft

1.正常拆系数fft,8次dft //#pragma GCC optimize(2) //#pragma GCC optimize(3) //#pragma GCC optimize(4) //#pragma GCC optimize("unroll-loops") //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector&q

luogu5282 【模板】快速阶乘算法

由于巨佬 shadowice1984 卡时限,本代码已经 T 请不要粘上去交 退役之后再写一个常数小的多项式取模吧 一句话题意:NP问题,求N!%P 吐槽:出题人太毒瘤...必须写任意模数NTT,而且加法取模还溢出... 我常数太大,粘的好久以前写的多项式取模,卡了卡常才A,大家1e3 1e4不要写vector,不要参考下面的代码 orz shadowice1984 写 \(O(\sqrt n\log n)\) 吊打我的 \(O(\sqrt n\log^2 n)\) 以下是 \(O(\sqrt