[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;
}
posted @ 2023-06-15 18:25  Diavolo-Kuang  阅读(14)  评论(0编辑  收藏  举报