# [Luogu P1447] [BZOJ 2005] [NOI2010]能量采集

### 输入输出样例

#### 输入样例#1：

5 4

#### 输出样例#1：

36

#### 输入样例#2：

3 4

#### 输出样例#2：

20

### 解题分析

$\sum _{i=1}^{n}\sum _{j=1}^{m}gcd\left(i,j\right)\phantom{\rule{0ex}{0ex}}=\sum _{d=1}^{n}d\sum _{i=1}^{n}\sum _{j=1}^{m}\left[gcd\left(i,j\right)=d\right]\phantom{\rule{0ex}{0ex}}=\sum _{d=1}^{n}d\sum _{i=1}^{⌊\frac{n}{d}⌋}\sum _{i=1}^{⌊\frac{m}{d}⌋}\left[gcd\left(i,j\right)=1\right]\phantom{\rule{0ex}{0ex}}=\sum _{d=1}^{n}d\sum _{i=1}^{⌊\frac{n}{d}⌋}\sum _{i=1}^{⌊\frac{m}{d}⌋}\sum _{k|gcd\left(i,j\right)}\mu \left(k\right)\phantom{\rule{0ex}{0ex}}=\sum _{d=1}^{n}d\sum _{k=1}^{⌊\frac{n}{d}⌋}⌊\frac{n}{kd}⌋⌊\frac{m}{kd}⌋\mu \left(k\right)$

$\phantom{\rule{0ex}{0ex}}=\sum _{d=1}^{n}d\sum _{k=1}^{⌊\frac{n}{d}⌋}⌊\frac{n}{T}⌋⌊\frac{m}{T}⌋\mu \left(k\right)\phantom{\rule{0ex}{0ex}}=\sum _{T=1}^{n}⌊\frac{n}{T}⌋⌊\frac{m}{T}⌋\sum _{k|T}\mu \left(k\right)×\frac{T}{k}\phantom{\rule{0ex}{0ex}}=\sum _{T=1}^{n}⌊\frac{n}{T}⌋⌊\frac{m}{T}⌋×\varphi \left(T\right)$

$O\left(N\right)$$O(N)$预处理$\varphi \left(T\right)$$\phi(T)$$O\left(N\right)$$O(N)$$O\left(\sqrt{N}\right)$$O(\sqrt N)$（下底分块）回答询问。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <algorithm>
#define R register
#define IN inline
#define gc getchar()
#define W while
#define MX 100050
bool npr[MX];
int phi[MX], pri[MX], pcnt, n, m;
void getphi()
{
phi[1] = 1; R int tar;
for (R int i = 2; i <= n; ++i)
{
if(!npr[i]) pri[++pcnt] = i, phi[i] = i - 1;
for (R int j = 1; j <= pcnt; ++j)
{
tar = pri[j] * i;
if(tar > n) break;
npr[tar] = true;
if(!(i % pri[j])) {phi[tar] = phi[i] * pri[j]; break;}
phi[tar] = phi[i] * (pri[j] - 1);
}
}
}
int main(void)
{
long long ans = 0;
scanf("%d %d", &n, &m);
getphi();
if(n > m) std::swap(n, m);
for (R int i = 1; i <= n; ++i) ans += 1ll * (n / i) * (m / i) * phi[i];
printf("%lld", ans * 2 -  1ll * n * m);//注意炸int
}


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