求助,莫名WA

P4245 【模板】任意模数多项式乘法

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了一半


|