给多项式AB,和模数P,求卷积后的膜P的值
注意精度!!!
不开long double 会出错
不在后面加0.5会出错
不一个个模P会出错
#include<bits/stdc++.h>
#define int long long
#define double long double
using namespace std;
const int N=1e6+10;
const int C=32768;
int p,x;
const double PI = acos(-1);
struct Complex{
double x,y;
Complex operator+(const Complex &t){return {x+t.x,y+t.y};}
Complex operator-(const Complex &t){return {x-t.x,y-t.y};}
Complex operator*(const Complex &t){return {x*t.x-y*t.y,x*t.y+y*t.x};}
}a[N],b[N],a2[N];
int n,m,tot=1,bit,r[N];
void fft(Complex a[],int inv){
for(int i=0;i<tot;i++){
if(i<r[i])swap(a[i],a[r[i]]);
}
for(int mid=1;mid<tot;mid*=2){
auto w1=Complex({cos(PI/mid),inv*sin(PI/mid)});
for(int i=0;i<tot;i+=mid*2){
auto wk=Complex({1,0});
for(int j=0;j<mid;j++,wk=wk*w1){
auto x=a[i+j],y=wk*a[i+j+mid];
a[i+j]=x+y;
a[i+j+mid]=x-y;
}
}
}
if(inv==1)return;
for(int i=0;i<tot;i++)a[i].x/=tot,a[i].y/=tot;
}
signed main(){
ios::sync_with_stdio(0);
cin>>n>>m>>p;
for(int i=0;i<=n;i++){
cin>>x;
a[i].x=x/C;
a[i].y=x%C;
a2[i].x=x/C;
a2[i].y=-(x%C);
}
for(int i=0;i<=m;i++){
cin>>x;
b[i].x=x/C;
b[i].y=x%C;
}
while(tot<n+m+1)tot*=2,bit++;
for(int i=0;i<tot;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(bit-1));
fft(a,1),fft(b,1),fft(a2,1);
for(int i=0;i<tot;i++)a[i]=a[i]*b[i],a2[i]=a2[i]*b[i];
fft(a,-1),fft(a2,-1);
for(int i=0;i<n+m+1;i++){
int ac=(a[i].x+a2[i].x)/2+0.5;
int adbc=(a[i].y+0.5);
int bd=(a2[i].x-a[i].x)/2+0.5;
int ans=ac*C%p*C%p+adbc*C%p+bd;
cout<<ans%p<<" ";
}
}
预处理单位根就可以避免 long double 了吧
5 次 FFT 的 MTT 还是太慢了,快来写 4 次 FFT 的吧!
%