【数论】狄利克雷卷积

1.定义

2.求法

对于卷积的第n项可以直接枚举约数,在根号n的时间内计算

但是对于狄利克雷卷积的前n项

h[i]=\sum_{ d | i }f[d]*g[i/d]

如果一项一项算的话就需要n根号n,但实际上可以优化

设x=d,y=i/d分别枚举x,y对于h[x*y]+=f[x]*g[y]即可。
时间复杂度O(n log n)

Code

F(i,1,n) h[i]=0;
F(i,1,n){
    F(j,1,n/i) h[i*j]=(h[i*j]+f[i]*g[j]%mod)%mod;
}
F(i,1,n) printf("%d ",h[i]);

对于卷k次的还可以用快速幂优化

while(k){
    if(k&1){
        tot++;
        if(tot==1){F(i,1,n) g[i]=t[i];}
        else{
            F(i,1,n) now[i]=0;
            F(i,1,n){
                F(j,1,n/i) now[i*j]=(now[i*j]+g[i]*t[j]%M)%M;
            }
            F(i,1,n) g[i]=now[i];
        }
    }
    F(i,1,n) now[i]=0;
    F(i,1,n){
        F(j,1,n/i) now[i*j]=(now[i*j]+t[i]*t[j]%M)%M;
    }
    F(i,1,n) t[i]=now[i];
    k>>=1;
}

例题:

1.5031. 【NOI2017模拟3.27】B

猜你喜欢

转载自blog.csdn.net/zsjzliziyang/article/details/107749294