一.題目鏈接:
UVA-11426
二.題目大意:
三.分析:
貼一個聚聚的題解,自然不是我這般蒟蒻能想到的...
還有一點困擾了我好久,就是該如何快速的計算 F[n].
如聚聚博客中寫到
本蒟蒻只想到了 的複雜度計算 F[],被自己蠢哭 _(:3」∠)_
正解是分別計算當 gcd(x, j) = i 時對 F[] 的貢獻,易得 i | j,複雜度爲
四.代碼實現:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = (int)4e6;
bool is_prime[M + 5];
int cnt, prime[M + 5];
int phi[M + 5];
ll sum[M + 5];
void init()
{
cnt = 0;
memset(is_prime, 1, sizeof(is_prime));
is_prime[0] = is_prime[1] = 0;
for(int i = 2; i <= M; ++i)
{
if(is_prime[i])
{
prime[++cnt] = i;
phi[i] = i - 1;
}
for(int j = 1; j <= cnt && i * prime[j] <= M; ++j)
{
is_prime[i * prime[j]] = 0;
if(i % prime[j] == 0)
{
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] * (prime[j] - 1);
}
}
}
int main()
{
init();
for(int i = 1; i <= M; ++i)
{
for(int j = 2 * i; j <= M; j += i)
{
sum[j] += 1ll * i * phi[j / i];
}
}
for(int i = 1; i <= M; ++i)
sum[i] += sum[i - 1];
int n;
while(~scanf("%d", &n) && n)
{
printf("%lld\n", sum[n]);
}
return 0;
}