1与任何数互质
4和15互质,4 15都不是质数,但互质 即gcd(4,15)=1
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int maxn=3e6+7;
int p[220000],phi[maxn];
//欧拉线性筛通过唯一分解法删合数(min质数*剩余部分)12=2*6,通过质数2来删
//线性筛基础上增加phi数组实现求n以内全部数的欧拉函数值
void f(){
int cnt=0;
memset(phi,0,sizeof(phi);
phi[1]=1;
for(int i=2;i<=maxn-1;i++){
//vis可舍去,直接phi初始化为0,若phi仍为0,说明还未访问
if(!phi[i]) {
p[++cnt]=i;
phi[i]=i-1;
//质数i的欧拉函数值为i-1
}
//利用已有的cnt个质数,和i相乘产生合数删去,知道某个质数和i不互质跳出。轮到i+1
for(int j=1;j<=cnt&&i*p[j]<maxn-1;j++){
//i是p[j]的倍数 。实现线性O(n)的关键
if(i%p[j]==0){
phi[i*p[j]]=phi[i]*p[j];
break;
}
//i和p[j]互质
phi[i*p[j]]=phi[i]*(p[j]-1);
}
}
}
int main(){
int a,b;
ll ans;
//1的欧拉函数值为1.欧拉函数值即1~n内有多少个数和n互质
memset(vis,0,sizeof(vis));
f();
while(~scanf("%d%d",&a,&b)){
ans=0;
for(int i=a;i<=b;i++)
ans+=phi[i];
cout<<ans<<endl;
}
return 0;
}
/*由于多个数组,且最终值要存在ll里,如果开一个数组专门存前缀和 或开一个ll数组 都会超内存。
所以就不用前缀和了,这样省点内存,也多不了多少时间 */