社区讨论

警示后人,如果你WA45pts

P4238【模板】多项式乘法逆参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo2wb3nb
此快照首次捕获于
2023/10/23 20:50
2 年前
此快照最后确认于
2023/10/23 20:50
2 年前
查看原帖
并且是测试点 #1,#6->#15 WA,
那么检查一下,你做 NTT 的时候 NN 的大小有没有开够 QwQ
CPP
    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,虽说常数大概是数组的两倍,但是这种写法几乎没有细节:
CPP
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;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...