题目描述
如果不同的整数X和Y的最大公约数为1,则称X和Y为互质数。显然,X和Y互质等价于Y和X互质。给出整数N,求1~N之间,有多少个数对(X,Y)是互质数。
例如N=5时,(1,2) , (1,3), (1,4), (1,5), (2,3), (2,5), (3,4), (3,5), (4,5)共9对数是互质数。
思路
很容易想到暴搜,两重循环,模拟 x 和 y ,再判定是否互质,但数据一旦过大,就会超时,那有不有什么快速的方法解题
就要引出主题欧拉函数了(如果不了解,点击查看),欧拉函数求的是 n 以内与 n 互质数的个数,那么只需要循环一遍 n ,累加其欧拉函数之和就可以迅速求出结果了。
代码
结合代码理解
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int n , ans , pr[10007] , ph[10007] , cnt ;
bool vis[10007] ;
int main() {//结合了欧拉筛法
ph[1] = 1 ;
scanf("%d", &n );
for(int i = 2 ; i <= n ; ++ i ) {//分解质因数和初始化
if(!vis[i]) {
cnt ++ ;
pr[cnt] = i ;
ph[i] = i - 1 ;
}
for(int j = 1 ; j <= cnt && i * pr[j] <= n ; ++ j ) {//欧拉筛法
vis[ i * pr[j] ] = 1 ;
if( i % pr[j] == 0 ) {
ph[ pr[j] * i ] = ph[i] * pr[j] ;
break;
}
else
ph [ pr[j] * i] = ph[i] * (pr[j] - 1 );
}
}
for(int i = 2 ; i <= n ; ++ i )
ans += ph[i];//累加结果
cout<<ans;
return 0;
}