# [SDOI2015]约数个数和(莫比乌斯反演)

$\inline d(x)$表示$\inline x$的约数个数,求$\inline T$$\inline \sum_{i=1}^{N} \sum_{j=1}^{M} d(ij)$

$\inline d(xy)=\sum_{i|x}\sum_{j|y} [gcd(i,j)==1]$中只考虑$\inline p_1$

$\inline gcd(i,j)==1$只当$\inline p_1$$\inline i$中出现$\inline j$中不出现的$\inline a$种, $\inline i$中不出现$\inline j$中出现的$\inline b$种, 都不出现的$\inline 1$种,所以贡献为$\inline (a+b+1)$,等式成立

$\inline 1-N,M$中约数作为枚举项, 式子变为 $\inline \sum_{i=1}^N \sum_{j=1}^M [\frac{N}{i}] [\frac{M}{j}] [gcd(i,j)==1]$($\inline i,j$相当于上式$\inline x,y$,不过是整体考虑每个$\inline x,y$贡献)

$\inline f(d)=\sum\sum [\frac{N}{i}] [\frac{M}{j}] [gcd(i,j)==d], \ F[d]=\sum\sum [\frac{N}{i}] [\frac{M}{j}] [d|gcd(i,j)]$($\inline F(n)$条件比$\inline f(n)$更松,也更易求)

$\inline f(1)=\sum_{1|n} \mu (\frac{n}{1}) F(n)=\sum_{d=1}^{min(N,M)} \sum_{x=1}^{[\frac{N}{d}]} [\frac{N}{xd}] \sum_{y=1}^{[\frac{M}{d}]} [\frac{M}{yd}]$

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

using LL = long long;
const int MAXN = 5e4 + 5;
int T, N, M;
bool noprime[MAXN];
int prime[MAXN], cnt_p, mu[MAXN];
int pre[MAXN], sum[MAXN];
void Euler_Sieve(int top);

int main(){
ios::sync_with_stdio(false);
Euler_Sieve(MAXN - 5);
cin >> T;
while(T--){
cin >> N >> M;
int l, r, top = min(N, M); LL ans = 0;
for(l = 1; l <= top; l = r + 1){
r = min(N / (N / l), M / (M / l));
ans += 1LL * (pre[r] - pre[l - 1]) * sum[N / l] * sum[M / l];
}
cout << ans << endl;
}
return 0;
}

void Euler_Sieve(int top){
int i, j;
mu[1] = 1;
for(i = 2; i <= top; i++){
if(!noprime[i]) prime[++cnt_p] = i, mu[i] = -1;
for(j = 1; j <= cnt_p && prime[j] * i <= top; j++){
noprime[prime[j] * i] = true;
if(i % prime[j] == 0) break;
mu[prime[j] * i] = -mu[i];
}
}

for(i = 1; i <= top; i++) pre[i] = pre[i - 1] + mu[i];

int l, r;
for(i = 1; i <= top; i++){
for(l = 1; l <= i; l = r + 1){
r = i / (i / l);
sum[i] += 1LL * (i / l) * (r - l + 1);
}
}
}
`

©️2019 CSDN 皮肤主题: 精致技术 设计师: CSDN官方博客