[hdu5628]Clarke and math(dirichlet卷积)

本文详细介绍了狄利克雷卷积的概念及其性质,并通过一个具体的编程实例演示了如何运用快速幂运算来解决相关问题。

传送门
狄利克雷卷积定义:\[(f*g)(n)=\sum_{d|n}f(d)*g({\frac n d})\]狄利克雷卷积满足交换律:\[f*g=g*f\]结合律:\[(f*g)*h=f*(g*h)\]还有这么几个性质:\[f*\varepsilon=f\] \[f*1=\sum_{d|n}f(d)\]其中\[1(n)=1,\varepsilon(n)=[n=1]\]我们做这个题就是用的上面那条,题目中的式子可以化成这样:\[1^k*f\]然后快速幂就好了。
代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
    int x=0;char ch=' ';int f=1;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')f=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
const int p=1e9+7;
int n,k;
ll a[100001];
void dirichlet(ll *ans,ll *f){
    memset(a,0,sizeof(a));
    for(int i=1;i*i<=n;i++){
        a[i*i]=(a[i*i]+ans[i]*f[i])%p;
        for(int j=i+1;j*i<=n;j++){
            a[i*j]=(a[i*j]+ans[i]*f[j])%p;
            a[i*j]=(a[i*j]+ans[j]*f[i])%p;
        }
    }
    for(int i=1;i<=n;i++)ans[i]=a[i];
}
ll f[100001],ans[100001],x[100001];
void ksm(){
    int b=k;
    while(b){
        if(b&1){
            dirichlet(ans,x);
        }
        dirichlet(x,x);
        b>>=1;
    }
}
void solve(){
    for(int i=1;i<=n;i++){
        f[i]=read();
        x[i]=1;
        ans[i]=0;
    }
    ans[1]=1;
    ksm();
    dirichlet(f,ans);
    for(int i=1;i<n;i++){
        printf("%lld ",f[i]);
    }
    printf("%lld\n",f[n]);
}

int T;
int main(){
    T=read();
    while(T--){
        n=read();k=read();
        solve();
    }
    return 0;
}

转载于:https://www.cnblogs.com/stone41123/p/7605431.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值