# BZOJ 2005: [Noi2010]能量采集(莫比乌斯反演)

## Solution

i=1nj=1m2gcd(i,j)1

(2i=1nj=1mgcd(i,j))nm

i=1nj=1mgcd(i,j)

F(n)$F(n)$f(n)$f(n)$是两个定义在正整数域上的数论函数，且F(n)=d|nf(d)$F(n)=\sum_{d|n}f(d)$,那么有

f(n)=d|nμ(d)F(nd)$f(n)=\sum_{d|n}\mu(d)F({n\over d})$

f(n)=n|dμ(dn)F(d)$f(n)=\sum_{n|d}\mu({d\over n})F(d)$

n=1明显成立。

n=px11px22px33...pxkk$n=p_1^{x_1}p_2^{x_2}p_3^{x_3}...p_k^{x_k}$

d|nμ(d)=r=0kCrk(1)r

d|nμ(d)=r=0kCrk(1)r1kr

(a+b)n=r=0nCrnarbnr

d|nμ(d)=(1+1)k=0(n>1)

mg=1gngi=1mgj=1e(gcd(i,j))$\sum_{g=1}^mg\sum_{i=1}^{\lfloor{n \over g}\rfloor}\sum_{j=1}^{\lfloor{m \over g}\rfloor}e(gcd(i,j))$

=mg=1gngi=1mgj=1t|gcd(i,j)μ(t)$=\sum_{g=1}^mg\sum_{i=1}^{\lfloor{n \over g}\rfloor}\sum_{j=1}^{\lfloor{m \over g}\rfloor}\sum_{t|gcd(i,j)}\mu(t)$

=mg=1gmgt=1μ(t)ngtmgt$=\sum_{g=1}^mg\sum_{t=1}^{\lfloor{m \over g}\rfloor}\mu(t)\lfloor{n \over gt}\rfloor\lfloor{m \over gt}\rfloor$

s=gt$s=gt$
=ms=1nsmst|sμ(t)st$=\sum_{s=1}^m\lfloor{n \over s}\rfloor\lfloor{m \over s}\rfloor\sum_{t|s}\mu(t){s \over t}$

μid=μϕI=ϕe=ϕ

Ans=s=1mnsmsϕ(s)

f(i)=nid=1g(di)$f(i)=\sum_{d=1}^{\lfloor{n\over i}\rfloor}g(d*i)$=>g(i)=nid=1f(di)μ(d)$=>g(i)=\sum_{d=1}^{\lfloor{n \over i}\rfloor} f(d*i)\mu(d)$

f(x)=x|d,d<=ng(d)$f(x)=\sum_{x|d,d<=n}g(d)$=>g(x)=x|d,d<=nf(d)μ(dx)$=>g(x)=\sum_{x|d,d<=n}f(d)\mu({d \over x})$

f(d)=ndi=1g(di)μ(i)$f(d)=\sum_{i=1}^{\lfloor{n \over d}\rfloor} g(d*i)\mu(i)$

f(d)=ndi=1μ(i)ndimdi$f(d)=\sum_{i=1}^{\lfloor{n \over d}\rfloor}\mu(i)\lfloor{n \over {di}}\rfloor\lfloor{m \over {di}}\rfloor$

ng=1gndi=1μ(i)ndimdi(n<m)$\sum_{g=1}^ng\sum_{i=1}^{\lfloor{n \over d}\rfloor}\mu(i)\lfloor{n \over {di}}\rfloor\lfloor{m \over {di}}\rfloor(n

## Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define N 100010

using namespace std;

typedef long long LL;
int n, m, cnt;
bool vis[N];
int prime[N];
LL phi[N], sum[N];

void Get_Phi(){
vis[1] = true;
phi[1] = 1ll;
for(int i = 2; i <= n; i++){
if(!vis[i]){
prime[++cnt] = i;
phi[i] = i - 1;
}
for(int j = 1; j <= cnt && i * prime[j] <= n; j++){
vis[i * prime[j]] = true;
if(i % prime[j] == 0){
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
else  phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
sum[0] = 0ll;
for(int i = 1; i <= n; i++)  sum[i] = sum[i-1] + phi[i];
}

LL Get_Ans(){
LL res = 0ll;
int last;
for(int i = 1; i <= n; i = last+1){
last = min(n/(n/i), m/(m/i));
res += (LL)(n/i) * (LL)(m/i) * (sum[last] - sum[i-1]);
}
return res * 2 - (LL)n * (LL)m;
}

int main(){

freopen("bzoj2005.in", "r", stdin);
freopen("bzoj2005.out", "w", stdout);

scanf("%d%d", &n, &m);
if(n > m)  swap(n, m);

Get_Phi();

printf("%lld\n", Get_Ans());

return 0;
}


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