有人写四次FFTAC此题的吗

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

chenkuowen01 @ 2019-01-15 18:20:38

貌似被卡精度了,过不去怎么办。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
const ld pi=acos(-1);
const int MAX_N=1<<19|5;
struct C{
    ld x,y;
    inline C operator+(C b){ return (C){x+b.x,y+b.y}; }
    inline C operator-(C b){ return (C){x-b.x,y-b.y}; }
    inline C operator*(C b){ return (C){x*b.x-y*b.y,x*b.y+y*b.x}; }
    inline C operator!(){ return (C){x,-y}; }
};
inline void FFT(C a[],int n,int t){
    for(int i=0,pos=0;i<n;++i){
        if(i<pos) swap(a[i],a[pos]);
        for(int p=n>>1;(pos^=p)<p;p>>=1);
    }
    static C p[MAX_N]; p[0]=(C){1,0};
    for(int step=1;step<n;step<<=1){
        C w=(C){cos(pi/step),t*sin(pi/step)};
        for(int i=1;i<step;++i) p[i]=p[i-1]*w;
        for(int i=0;i<n;i+=step<<1)
            for(int j=i;j<i+step;++j){
                C x=a[j],y=a[j+step]*p[j-i];
                a[j]=x+y; a[j+step]=x-y;
            }
    }
    if(t==-1) for(int i=0;i<n;++i) a[i]=a[i]*(C){1.0/n,0};
}
C a[MAX_N],b[MAX_N],c[MAX_N],d[MAX_N],p[MAX_N],q[MAX_N];
int getint(){
    int ret=0;
    char c=getchar();
    for(;c<'0'||c>'9';c=getchar());
    for(;c>='0'&&c<='9';c=getchar())
        ret=ret*10+c-'0';
    return ret;
}
int main(){
    int n,m,mod; scanf("%d%d%d",&n,&m,&mod);
    int m0=sqrt(mod)+1,top;
    for(top=1;top<=2*max(n,m);top<<=1);
    for(int i=0;i<=n;++i){
        int key=getint();
        p[i]=(C){(ld)(key/m0),(ld)(key%m0)};
    }
    for(int i=0;i<=m;++i){
        int key=getint();
        q[i]=(C){(ld)(key/m0),(ld)(key%m0)};
    }
    FFT(p,top,1); FFT(q,top,1);
    for(int i=0;i<top;++i){
        int j=i?top-i:0;
        C a1,b1,c1,d1;
        a1=(p[i]+!p[j])*(C){0.5,0};
        b1=(p[i]-!p[j])*(C){0,-0.5};
        c1=(q[i]+!q[j])*(C){0.5,0};
        d1=(q[i]-!q[j])*(C){0,-0.5};
        a[i]=a1*c1+(C){0,1}*a1*d1;
        c[i]=c1*b1+(C){0,1}*b1*d1;
    }
    FFT(a,top,-1); FFT(c,top,-1);
    for(int i=0;i<=n+m;++i){
        ll a1=(ll)(a[i].x+0.5);
        ll b1=(ll)(a[i].y+0.5);
        ll c1=(ll)(c[i].x+0.5);
        ll d1=(ll)(c[i].y+0.5);
        printf("%lld ",(a1*m0%mod*m0%mod
            +(b1+c1)*m0%mod+d1)%mod);
    }
    return 0;
}

by King_of_gamers @ 2019-01-15 18:30:12

Orz,tql,无敌啊,AKIOI


by 142857cs @ 2019-01-15 18:32:04

没办法了


by 142857cs @ 2019-01-15 18:36:14

写3模数NTT吧


by Tomarange @ 2019-01-15 18:44:55

单位复数根那里不要一路乘过去,每次重新算,不然精度爆的很严重


by shadowice1984 @ 2019-01-15 18:45:21

@142857cs

三模ntt废物啊,写拆系数fft+三次变两次啊

似乎我的三次变两次就没有问题,不知道怎么肥四


by waaadreamer @ 2019-01-15 18:48:02

@chenkuowen01 单位根直接用cos和sin算,乘法精度会炸。

我就是4次FFT过的


by ButterflyDew @ 2019-01-15 18:48:03

我也死活过不去


by ButterflyDew @ 2019-01-15 18:48:46

就在底下一个帖子嘤嘤嘤


by Qiuly @ 2019-01-15 18:55:15

表示不会 FFT


by 142857cs @ 2019-01-15 18:56:32

@Qiuly 那你进来干什么?


| 下一页