题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2824
题目大意:求\(\sum_{i=a}^{b}\phi \left(i \right)\)
令\(sum\left(n \right)=\sum_{i=1}^{n}\phi \left(n \right)\),则问题转化为\(sum\left ( b \right )-sum\left ( a-1 \right )\)
若\(n=p_1^{k_1}p_2^{k_2}\cdots p_r^{k_r}\)
则\(\phi \left ( n \right )=n\prod_{p|n}\left ( 1-\frac{1}{p} \right )=n\prod_{p|n}\left ( \frac{p-1}{p} \right )\)
可利用线性筛法求出所有\(\phi \left ( n \right )\)
线性筛法求欧拉函数代码
#define N 3000010
#define LL __int64
LL euler[N];
void getEuler(){
memset(euler,0,sizeof(euler));
euler[1]=1;
for(int i=2;i<=N;++i){
if(!euler[i]){
for(int j=i;j<=N;j+=i){
if(!euler[j])
euler[j]=j;
euler[j]=euler[j]/i*(i-1);
}
}
}
}
题目代码:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
#define MAX(a,b) ((a>b)?(a):(b))
#define MIN(a,b) ((a<b)?(a):(b))
#define N 3000010
#define INF 1<<30
#define ll __int64
ll euler[N+10];
void getEuler(){
memset(euler,0,sizeof(euler));
euler[1]=1;
for(int i=2;i<=N;++i){
if(!euler[i]){
for(int j=i;j<=N;j+=i){
if(!euler[j])
euler[j]=j;
euler[j]=euler[j]/i*(i-1);
}
}
}
}
void getSum(){
for(int i=3;i<=N;++i){
euler[i]+=euler[i-1];
}
}
int main(){
//freopen("C:\\Users\\F\\Desktop\\in.txt", "r", stdin);
//freopen("C:\\Users\\F\\Desktop\\out.txt", "w", stdout);
getEuler();
getSum();
int a,b;
while(scanf("%d%d",&a,&b)!=EOF){
printf("%I64d\n",euler[b]-euler[a-1]);
}
return 0;
}