Sum of gcd of Tuples (Hard)

题面描述

题解

\(\sum_{a_1=1}^{k}\sum_{a_2=1}^{k}···\sum_{a_n=1}^{k}gcd(a_1,a_2,···,a_n)\)
\(f(d)=\sum_{a_1=1}^{k}\sum_{a_2=1}^{k}···\sum_{a_n=1}^{k}[gcd(a_1,a_2,···,a_n)=d]\)
\(g(d)=\sum_{d|d',d'\leq k}f(d')=[\frac{n}{d}]^n\)
根据莫比乌斯反演定理
\(f(d)=\sum_{d|d',d'\leq k}\mu(\frac{d'}{d})g(d')\)
\(ans=\sum_{i=1}^{k}f(i)\)

点击查看代码
#include<functional>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<queue>
#include<deque>
#define ll long long 
using namespace std;
const int maxn=1e5+101;
const int MOD=1e9+7;
const int inf=2147483647;
int read(){
    int x=0,f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    return x*f;
}
int mu[maxn];
int tot,is[maxn],prime[maxn];
int n,k;
ll g[maxn];
void get_mu(){
    mu[1]=1;
    for(int i=2;i<=k;i++){
        if(!is[i])prime[++tot]=i,mu[i]=-1;
        for(int j=1;j<=tot && prime[j]<=k/i;j++){
            is[i*prime[j]]=1;
            if(i%prime[j]==0)break;
            mu[i*prime[j]]=-mu[i];
        }
    }
}
ll power(ll x,ll y){
    ll ans=1;
    while(y){
        if(y&1)ans=ans*x%MOD;
        y>>=1;x=x*x%MOD;
    }
    return (ans%MOD+MOD)%MOD;
}
int main(){
    n=read();k=read();get_mu();
    for(int i=1;i<=k;i++)g[i]=power((ll)(k/i),(ll)n);
    ll ans=0;
    for(int i=1;i<=k;i++){
        ll num=0;
        for(int j=i;j<=k;j+=i){
            (num+=(ll)mu[j/i]*g[j]%MOD)%=MOD;
        }
        num=(num+MOD)%MOD;
        (ans+=num*i%MOD)%=MOD;
        ans=(ans+MOD)%MOD;
    }
    printf("%lld",ans%MOD);
    return 0;
}
posted @ 2021-11-03 13:03  I_N_V  阅读(40)  评论(0编辑  收藏  举报