警示后人,如果你WA45pts
查看原帖
警示后人,如果你WA45pts
663681
C_liar楼主2023/3/22 20:22

并且是测试点 #1,#6->#15 WA,

那么检查一下,你做 NTT 的时候 NN 的大小有没有开够 QwQ

    void convolution(vector<int>& a,vector<int> c){
        prework(a.size()*2);/*prework(a.size()+c.size()+1)*/
        int tmp=a.size();
        a.resize(N),c.resize(N);
        NTT(a,0),NTT(c,0);
        for(int i=0;i<N;i++) a[i]=mul(c[i],pls(2,mod-mul(a[i],c[i])));
        NTT(a,1);
        a.resize(tmp);
    }

解释一下,prework(n) 中的 nn 是 NTT 要处理的数组长度,之后会转化成 22 的幂,aa 是传进去的 F(x)F(x)ccG1(x)G_1(x),函数返回 G(x)G(x)

这里之所以要开成 2n2n 的点值,是因为 G1(x)(2F(x)G1(x))G_1(x)(2-F(x)G_1(x)) 最高次幂可能是 2n2n 级别的,点值一定要开够,再对 xnx^n 取模。

另外推荐大家用 std::vector,虽说常数大概是数组的两倍,但是这种写法几乎没有细节:

vector<int> PolyInv(vector<int> a){
    if(a.size()==1u){
        a[0]=inv(a[0]);
        return a;
    }
    vector<int> b((a.size()+1)>>1);
    for(int i=0;i<(int)b.size();i++) b[i]=a[i];
    b=PolyInv(b);
    ntt::convolution(a,b);
    return a;
}
2023/3/22 20:22
加载中...