asd_a @ 2019-08-08 13:21:16
mine
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
const long double pi=std::acos(-1.0);
struct cp{
long double x,y;
cp(){}cp(long double xx,long double yy){x=xx;y=yy;}
cp operator +(cp a){return cp(x+a.x,y+a.y);}
cp operator -(cp a){return cp(x-a.x,y-a.y);}
cp operator *(cp a){return cp(x*a.x-y*a.y,x*a.y+y*a.x);}
}a[N],b[N],c[N],d[N];
cp conj(cp a){return cp(a.x,-a.y);}
int rev[N],p;
inline void fft(cp* A,int lim){
for(int i=0;i<lim;i++)
if(i<rev[i])swap(A[i],A[rev[i]]);
for(int mid=1;mid<lim;mid<<=1){
cp W=cp(std::cos(pi/mid),std::sin(pi/mid));
for(int j=0;j<lim;j+=(mid<<1)){
cp w=cp(1.0,0);
for(int i=j;i<mid+j;i++,w=w*W){
cp t=w*A[mid+i];
A[i+mid]=A[i]-t;A[i]=A[i]+t;
}
}
}
}
inline void mul(int *A,int *B,int lim,int *C){
for(int i=0;i<lim;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)*(lim>>1));
for(int i=0;i<lim;i++){
a[i]=cp(A[i]&32767,A[i]>>15);
b[i]=cp(B[i]&32767,B[i]>>15);
}
fft(a,lim);fft(b,lim);
for(int i=0;i<lim;i++){
cp na,nb,nc,nd;int j=(lim-i)&(lim-1);
na=(a[i]+conj(a[j]))*cp(0.5,0);nb=(a[i]-conj(a[j]))*cp(0,-0.5);
nc=(b[i]+conj(b[j]))*cp(0.5,0);nd=(b[i]-conj(b[j]))*cp(0,-0.5);
c[j]=na*nc+na*nd*cp(0,1.0);d[j]=nb*nc+nb*nd*cp(0,1.0);
}
fft(c,lim);fft(b,lim);
for(int i=0;i<lim;i++){
int na=((long long)(c[i].x/lim+0.5))%p;
int nb=((long long)(c[i].y/lim+d[i].y/lim+0.5))%p;
int nc=((long long)(d[i].y/lim+0.5))%p;
C[i]=((((long long)nc<<30)%p+((long long)nb<<15)%p)%p+(long long)na)%p;
}
}
int n,m,f[N],g[N],h[N];
int main(){
scanf("%d%d%d",&n,&m,&p);
for(int i=0;i<=n;i++)scanf("%d",&f[i]),f[i]%=p;
for(int i=0;i<=m;i++)scanf("%d",&g[i]),g[i]%=p;
int lim=1;
while(lim<=n+m)lim<<=1;
mul(f,g,lim,h);
for(int i=0;i<=n+m;i++)printf("%d ",(h[i]+p)%p);
return 0;
}
题解:
#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#define l putchar('\n')
#define file(x)freopen(x".in","r",stdin);freopen(x".out","w",stdout)
#define block 32768
#define rt register int
#define ll long long
using namespace std;
inline ll read(){
ll x=0;char zf=1;char ch=getchar();
while(ch!='-'&&!isdigit(ch))ch=getchar();
if(ch=='-')zf=-1,ch=getchar();
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();return x*zf;
}
void write(ll y){if(y<0)putchar('-'),y=-y;if(y>9)write(y/10);putchar(y%10+48);}
void writeln(const ll y){write(y);putchar('\n');}
int k,m,n,x,y,z,cnt,ans,p;
namespace any_module_NTT{
vector<int>R;
const double PI=acos(-1.0);
struct cp{
double x,y;
cp operator +(const cp s)const{return {x+s.x,y+s.y};}
cp operator -(const cp s)const{return {x-s.x,y-s.y};}
cp operator *(const cp s)const{return {x*s.x-y*s.y,x*s.y+y*s.x};}
}w[18][1<<17];
void FFT(const int n,vector<cp>&A){
A.resize(n);
for(rt i=0;i<n;i++)if(i>R[i])swap(A[i],A[R[i]]);
for(rt i=1,s=0;i<n;i<<=1,s++){
for(rt j=0;j<n;j+=i<<1){
for(rt k=0;k<i;k++){
const register cp x=A[j+k],y=w[s][k]*A[i+j+k];
A[j+k]=x+y,A[i+j+k]=x-y;
}
}
}
}
vector<int>Mul(vector<int>&x,vector<int>&y){
int sz=x.size()+y.size()-1,lim=1;
while(lim<=sz)lim<<=1;R.resize(lim);
for(rt i=0;(1<<i)<lim;i++)
for(rt j=0;j<(1<<i);j++)w[i][j]={cos(PI*j/(1<<i)),sin(PI*j/(1<<i))};
vector<cp>AB(lim),CD(lim),AC(lim),BC(lim);
for(rt i=1;i<lim;i++)R[i]=(R[i>>1]>>1)|(i&1)*(lim>>1);
for(rt i=0;i<x.size();i++)AB[i].x=((ll)x[i])&32767,AB[i].y=((ll)x[i])>>15;
for(rt i=0;i<y.size();i++)CD[i].x=((ll)y[i])&32767,CD[i].y=((ll)y[i])>>15;
FFT(lim,AB);FFT(lim,CD);
for(rt i=0;i<lim;i++){
static cp na,nb,nc,nd;const int pl=(lim-1)&(lim-i);
na=AB[i]+(cp){AB[pl].x,-AB[pl].y},nb=AB[i]-(cp){AB[pl].x,-AB[pl].y};
nc=CD[i]+(cp){CD[pl].x,-CD[pl].y},nd=CD[i]-(cp){CD[pl].x,-CD[pl].y};
const cp v1={0.5,0},v2={0,-0.5};
na=na*v1;nb=nb*v2;nc=nc*v1;nd=nd*v2;
AC[pl]=na*nc+na*nd*(cp){0,1};
BC[pl]=nb*nc+nb*nd*(cp){0,1};
}
FFT(lim,AC);FFT(lim,BC);
vector<int>ans(sz);
for(rt i=0;i<sz;i++){
ll v1=AC[i].x/lim+0.5,v2=AC[i].y/lim+BC[i].x/lim+0.5,v3=BC[i].y/lim+0.5;
ans[i]=(ll)((v3%p<<30)+(v2%p<<15)+v1)%p;
}
return ans;
}
}
using namespace any_module_NTT;
vector<int>A,B;
int main(){
n=read();A.resize(n+1);m=read();B.resize(m+1);p=read();
for(rt i=0;i<=n;i++)A[i]=read();for(rt i=0;i<=m;i++)B[i]=read();
A=Mul(A,B);
for(rt i=0;i<=n+m;i++)write((A[i]+p)%p),putchar(' ');
return 0;
}
by asd_a @ 2019-08-08 13:22:59
WA了一半