[ABC162E] Sum of gcd of Tuples (Hard)
题面翻译
给定\(n,k\),求
\[\sum^k_{a_1=1}\sum^k_{a_2=1}\sum^k_{a_3=1}\dots\sum^k_{a_n=1}gcd(a_1,a_2,a_3,\dots,a_n)\ mod\ 1000000007
\]
制約
- $ 2\ \leq\ N\ \leq\ 10^5 $
- $ 1\ \leq\ K\ \leq\ 10^5 $。
思路点拨
我们看到这么多 \(\gcd\) 的式子,我们自然想到莫比乌斯反演。
\[\sum_{d=1}^k d \sum_{a_1=1}^k \sum_{a_2=1}^k ... \sum_{a_n=1}^k [\gcd(a_1,a_2,...,a_n)=d]
\]
\[\sum_{d=1}^k d \sum_{a_1=1}^{\lfloor \frac{k}{d}\rfloor} \sum_{a_2=1}^{\lfloor \frac{k}{d}\rfloor} ... \sum_{a_n=1}^{\lfloor \frac{k}{d}\rfloor} [\gcd(a_1,a_2,...,a_n)=1]
\]
\[\sum_{i=1}^k d \sum_{t=1}^{\lfloor \frac{k}{d}\rfloor} \mu(t) (\lfloor \dfrac{k}{tk}\rfloor)^n
\]
蛮力算就是 \(O(n \log n \log n)\) 。
\(code\)
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
int n,m,k;
const int mod=1e9+7,N=1e5,MAXN=1e5+10;
int qpow(int a,int b){
int ans=1,base=a;
while(b){
if(b&1)ans=ans*base%mod;
base=base*base%mod;
b>>=1;
}
return ans;
}
int mu[MAXN];
bool vis[MAXN];
void prepare(){
for(int i=1;i<=N;i++)
mu[i]=1;
for(int i=2;i<=N;i++){
if(vis[i]) continue;
mu[i]=-1;
for(int j=i*2;j<=N;j+=i){
vis[j]=1;
mu[j]=-mu[j];
if(j%(i*i)==0) mu[j]=0;
}
}
}
signed main(){
prepare();
n=read(),k=read();
int ans=0;
for(int d=1;d<=k;d++)
for(int t=1;t<=(k/d);t++)
ans=(ans+(mu[t]+mod)*d%mod*qpow(k/(d*t),n)%mod)%mod;
cout<<ans;
return 0;
}