欧拉函数的原始公式是用n连乘(1-1/pi)。pi是n的素因子。我们可以通过一个n^2级筛法的方式去筛,这样就保证了每个合数都会被其所有素因子筛一次,只要在筛的时候在其结果上乘上1-1/pi)即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define maxn 3000005
double ans[maxn];
bool prime[maxn];
int next(int a)
{
a += 1;
while (!prime[a] && a < maxn)
a++;
if (!(a < maxn))
return 0;
return a;
}
int main()
{
//freopen("D:\\t.txt", "r", stdin);
for (int i = 0; i < maxn; i++)
{
ans[i] = i;
prime[i] = true;
}
for (long long i = 2; i != 0; i = next(i))
{
ans[i] *= (1 - 1.0 / i);
for (long long j = 2; i * j < maxn; j++)
{
ans[i * j] *= (1 - 1.0 / i);
prime[i * j] = false;
}
}
int a, b;
while (scanf("%d%d", &a, &b) != EOF)
{
long long sum = 0;
for (int i = a; i <= b; i++)
sum += ans[i];
printf("%I64d\n", sum);
}
return 0;
}