三模数NTT模板
Posted achenchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三模数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<cmath>
10 #include<set>
11 #include<map>
12 #define Formylove return 0
13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
15 const int N=524299,g=3;
16 typedef long long LL;
17 typedef double db;
18 typedef long double LD;
19 using namespace std;
20 int n,m,mod;
21 LL a[3][N],b[3][N],p[4]={998244353,167772161,469762049},gi[4]={332748118,55924054,156587350};
22 LL ans[N];
23
24 template<typename T>void read(T &x) {
25 char ch=getchar(); x=0; T f=1;
26 while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘)) ch=getchar();
27 if(ch==‘-‘) f=-1,ch=getchar();
28 for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar()) x=x*10+ch-‘0‘; x*=f;
29 }
30
31 LL ksc(LL a,LL b,LL p) {
32 LL tp=a*b-(LL)((LD)a/p*b+1.0e-8)*p;
33 return tp<0?tp+p:tp%p;
34 }
35
36 LL ksm(LL a,LL b,LL p) {
37 LL rs=1,bs=a%p;
38 while(b) {
39 if(b&1) rs=ksc(rs,bs,p);
40 bs=ksc(bs,bs,p);
41 b>>=1;
42 }
43 return rs;
44 }
45
46 int l,rev[N];
47 void FFT(int n,LL a[],int f,int p,int gi) {
48 For(i,0,n-1) if(i<rev[i]) swap(a[i],a[rev[i]]);
49 for(int i=1;i<n;i<<=1) {
50 LL wi=ksm((f==1)?g:gi,(p-1)/(i<<1),p);
51 for(int j=0,pp=(i<<1);j<n;j+=pp) {
52 LL w=1;
53 for(int k=0;k<i;k++,w=w*wi%p) {
54 LL x=a[j+k],y=w*a[j+k+i]%p;
55 a[j+k]=(x+y)%p; a[j+k+i]=(x-y+p)%p;
56 }
57 }
58 }
59 if(f==-1) {
60 LL inv=ksm(n,p-2,p);
61 For(i,0,n) a[i]=a[i]*inv%p;
62 }
63 }
64
65 int main() {
66 #ifdef ANS
67 freopen(".in","r",stdin);
68 freopen(".out","w",stdout);
69 #endif
70 read(n); read(m); read(mod);
71 For(i,0,n) { read(a[0][i]); a[1][i]=a[2][i]=a[0][i]; }
72 For(i,0,m) { read(b[0][i]); b[1][i]=b[2][i]=b[0][i]; }
73 m+=n;
74 for(n=1;n<=m;n<<=1) l++;
75 For(i,1,n) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
76 For(i,0,2) {
77 FFT(n,a[i],1,p[i],gi[i]);
78 FFT(n,b[i],1,p[i],gi[i]);
79 For(j,0,n) a[i][j]=a[i][j]*b[i][j]%p[i];
80 FFT(n,a[i],-1,p[i],gi[i]);
81 }
82 LL p1=p[0],p2=p[1],p3=p[2];
83 For(i,0,m) {
84 LL b1=a[0][i],b2=a[1][i],b3=a[2][i],b4;
85 b4=(ksc(ksc(b1,ksm(p2,p1-2,p1),p1*p2),p2,p1*p2)+ksc(ksc(b2,ksm(p1,p2-2,p2),p1*p2),p1,p1*p2))%(p1*p2);
86 LL k=((b3%p3-b4%p3+p3)%p3)*ksm(p1*p2,p3-2,p3)%p3;
87 ans[i]=(b4%mod+k*p1%mod*p2%mod)%mod;
88 }
89 For(i,0,m) printf("%lld ",ans[i]); puts("");
90 Formylove;
91 }
以上是关于三模数NTT模板的主要内容,如果未能解决你的问题,请参考以下文章