拉格朗日插值
模板 https://www.luogu.org/problemnew/show/P4781
离散傅里叶变换(DFT)
快速傅里叶变换(FFT)
https://blog.csdn.net/ggn_2015/article/details/68922404
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int maxn=2097156;//2097152 struct cp{ double r,i; }w[maxn],a[maxn],b[maxn]; inline cp operator + (const cp &x,const cp &y){ return (cp){x.r+y.r,x.i+y.i}; } inline cp operator - (const cp &x,const cp &y){ return (cp){x.r-y.r,x.i-y.i}; } inline cp operator * (const cp &x,const cp &y){ return (cp){x.r*y.r-x.i*y.i,x.r*y.i+x.i*y.r}; } int N,rev[maxn]; const double pi=acos(-1); inline void init(int n){ int bit=0; for(N=1;N<=n;N<<=1) bit++; for(int i=0;i<N;i++) w[i]=(cp){cos(2*pi*i/N),sin(2*pi*i/N)}; for(int i=0;i<(1<<bit);i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1)); } inline void fft(cp *x,int v){ if(v) for(int i=1;i<N;i++) if(i<N-i) swap(x[i],x[N-i]); for(int i=0;i<N;++i) if(i<rev[i])swap(x[i],x[rev[i]]); for(int i=1;i<N;i<<=1){ for(int j=0;j<N;j+=i<<1){ for(int k=0;k<i;++k){ cp p=w[N/(i<<1)*k]*x[i+j+k]; x[i+j+k]=x[j+k]-p;x[j+k]=x[j+k]+p; } } } if(v)for(int i=0;i<N;++i)x[i].r/=N,x[i].i/=N; } int main(){ int n,m; scanf("%d%d",&n,&m); for(int i=0;i<=n;i++) scanf("%lf",&a[i].r); for(int i=0;i<=m;i++) scanf("%lf",&b[i].r); init(n+m); fft(a,0);fft(b,0); for(int i=0;i<N;i++) a[i]=a[i]*b[i]; fft(a,1); for(int i=0;i<=n+m;++i)printf("%d ",(int)(a[i].r+0.5)); } /*init 把n搞成2的次幂 v=0 fft v=1 逆变换 (x+1)^2 逆变换单位根反过来,x数组反过来是等价的 */
快速数论变换(NTT)
NTT的优缺点
优点
能取模,FFT的复数你给我来取个模没有精度差,FFT浮点数的精度怎么也会出一点问题
由于均为整数操作(虽然取模多),NTT常数小,通常比一大堆浮点运算的FFT要快
缺点
多项式的系数都必须是整数模数有限制,NTT 题的模数通常都是相同的998244353
其实这些模数的原根通常都是3