题意:
题意是不是很清楚了,但是如何求呢,怎么换一种方法理解,题意是不是等同于求i与比i小的所有数的最大公约数,如果转换不明白可以想象成乘法口诀表,然后把所有i的最大公约数相加,一直加到n。
思想:本题的题意是否非常的清楚,那么我们怎么求呢?根据题意,是求所有i与比i小的所有数的最大公约数m,那么我们只要求出所有m,再把m相加,就是最后的结果。那么我们的重点是如何求m。所有i与比i小的所有数的最大公约数m这种求法像不像欧拉函数,欧拉函数是求i之前所有与i互质数的个数,那么如果我们知道与i互质数的个数, 同时根据这个公式gcd(a, b) = 1, gcd(a * t, b *t) = t,是不是就能知道这些数的最大公约数了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL maxn = 4e6+5;
LL pri[maxn], a[maxn];
void Prime()
{
memset(a,0, sizeof(a));
for(int i = 1; i <= maxn; i++)
{
pri[i] = i;
}
for(int i = 2; i <= maxn; i++)
{
if(pri[i] == i)
{
for(int j = i; j <= maxn; j += i)
{
pri[j] = pri[j]/i*(i-1);
}
}
for(int j = 1; j * i <= maxn; j++)
{
a[i*j] += j*pri[i];
}
}
for(int i = 1; i <= maxn; i++)
{
a[i] += a[i-1];
}
}
int main()
{
int n;
Prime();
while(cin>>n && n != 0)
{
printf("%lld\n", a[n]);
}
return 0;
}