# BZOJ 2005: [Noi2010]能量采集

$\LARGE Answer=2*(\sum _{i=1}^{n}\sum_{j=1}^m\gcd(i,j))-nm$

$\LARGE n=\sum _{d|n}\varphi \left( d\right)$

$\LARGE \sum ^{n}_{i=1}\sum ^{m}_{j=1}\gcd \left( i,j\right)$

$\LARGE =\sum ^{n}_{i=1}\sum ^{m}_{j=1}\sum _{d|\gcd \left( i,j\right) }\varphi \left( d\right)$

$\LARGE =\sum ^{\max \left( n,m\right) }_{d=1}\varphi \left( d\right) \sum ^{n/d}_{i=1}\sum ^{m/d}_{j=1}1$

$\LARGE =\sum ^{\max \left( n,m\right) }_{d=1}\varphi \left( n\right) \lfloor \dfrac {n}{d}\rfloor \lfloor \dfrac {m}{d}\rfloor$

/*
BZOJ 2005: [Noi2010]能量采集

莫比乌斯反演
*/
#include <cstdio>
#include <iostream>
#include <cmath>

#define rg register
#define Max 1000005
int p[Max], phi[Max];
bool is[Max];
typedef long long LL;
LL s[Max];
void Euler (int N)
{
int C = 0; phi[1] = 1; rg int i, j;
for (i = 2; i <= N; ++ i)
{
if (!is[i]) p[++ C] = i, phi[i] = i - 1;
for (j = 1; j <= C && i * p[j] <= N; ++ j)
{
is[i * p[j]] = true;
if (i % p[j] == 0) phi[i * p[j]] = phi[i] * p[j];
else phi[i * p[j]] = phi[i] * (p[j] - 1);
}
}
for (i = 1; i <= N; ++ i) s[i] = s[i - 1] + phi[i];
}
inline int min (int a, int b) { return a < b ? a : b; }

int main (int argc, char *argv[])
{
int N, M; scanf ("%d%d", &N, &M); rg int i, j;
if (N > M) std :: swap (N, M);
Euler (N);
}