码迷,mamicode.com
首页 > 其他好文 > 详细

三模数NTT模板

时间:2018-08-24 21:15:55      阅读:355      评论:0      收藏:0      [点我收藏+]

标签:--   ifd   getchar   code   ble   class   one   turn   freopen   

求两个多项式的卷积对任意数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 }
View Code

 

 

三模数NTT模板

标签:--   ifd   getchar   code   ble   class   one   turn   freopen   

原文地址:https://www.cnblogs.com/Achenchen/p/9531952.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!