LOJ528 「LibreOJ β Round #4」求和

LOJ528 「LibreOJ β Round #4」求和

先按照最常规的思路推一波:

\[\begin{aligned} &\sum_{i=1}^n\sum_{j=1}^m\mu^2(\gcd(i,j))\\ =&\sum_{d=1}^{\min(n,m)}\mu^2(d)\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=d]\\ =&\sum_{d=1}^{\min(n,m)}\mu^2(d)\sum_{t=1}^{\min(n,m)}\mu(t)\lfloor \frac{n}{dt}\rfloor \lfloor \frac{m}{dt}\rfloor\\ =&\sum_{x=1}^{\min(n,m)}\lfloor \frac{n}{x}\rfloor \lfloor \frac{m}{x}\rfloor\sum_{d|x}\mu^2(d)\mu(\frac x d) \end{aligned} \]

然后后面这个东西一定是个积性函数,所以可以求出质数及其幂次上的的值,最后整除分块即可。

然后有另一种更为简洁的思路:

有反演公式 \(\mu^2(x)=\sum_{d^2|x}\mu(d)\)

考虑证明。

\(x\)\(\texttt{square_free numbers}\),即其无平方因子,则 \(d\) 只能取 \(1\),显然成立。

\(x\)\(\texttt{square_free numbers}\),即其有平方因子,则左边显然为 \(0\)

设其含有某个平方因子 \(p_k\)

则对于所有的 \(d^2\),其中若 \(d\) 含有 \(p^2\),其对答案的贡献为 \(0\)

否则 \(d\) 含有 \(p\) 或不含 \(p\),显然这两种情况的个数相同,且根据莫比乌斯函数的定义,对于答案的贡献恰好相反,也就是贡献和为 \(0\)

所以有

\[\begin{aligned} &\sum_{i=1}^n\sum_{j=1}^m\mu^2(\gcd(i,j))\\ =&\sum_{i=1}^n\sum_{j=1}^m\sum_{d^2|\gcd(i,j)}\mu(d)\\ \end{aligned} \]

然后你发现我们只需要找到 \(\gcd(i,j)\) 为完全平方数或其倍数的数,所以我们直接枚举就好了。

/*---Author:HenryHuang---*/
/*---Never Settle---*/
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll maxn=4e6+5;
const ll mod=998244353;
ll P;
ll pri[maxn],mu[maxn],p[maxn],cnt;
void init(){
	mu[1]=1;
	for(ll i=2;i<=P;++i){
		if(!p[i]) pri[++cnt]=i,mu[i]=-1;
		for(ll j=1;j<=cnt&&pri[j]*i<=P;++j){
			p[pri[j]*i]=1;
			if(i%pri[j]==0){
				mu[pri[j]*i]=0;
				break;
			}
			else mu[pri[j]*i]=-mu[i];
		}
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	ll n,m;cin>>n>>m;
	if(n<m) swap(n,m);P=sqrt(n+0.5);init();
	ll ans=0;
	for(ll i=1;1ll*i*i<=n;++i){
		if(!mu[i]) continue;
		ll x=i*i;
		ans=(ll)(ans+mu[i]*(1ll*(n/x)%mod*((m/x)%mod))%mod+mod)%mod;
	}
	cout<<ans<<'\n';
	return 0;
}
posted @ 2021-02-25 15:10  Henry__Huang  阅读(199)  评论(0编辑  收藏  举报