题目https://vjudge.net/contest/70017#problem/O
题目大意:
给定m,求m内中任意两个数i和j的gcd之和
大佬题解:https://blog.csdn.net/duan_1998/article/details/71465256
题解就是根据互质的两个数,枚举出所有的可能性
比如gcd(2,3)=1,那么gcd(4,6)=2,gcd(6,9)=3,以此类推
如果按照这样枚举每一对互质的数并且一路乘到上限,那么是不会有漏掉的
而枚举互质的两个数可以利用欧拉函数,具体代码如下
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
ll ans[4000001];
ll euler[4000001];
void getEuler(){
memset(euler,0,sizeof(euler));
euler[1] = 1;
for(int i = 2;i <= 4000000;i++)
if(!euler[i])
for(int j = i;j <= 4000000; j += i){
if(!euler[j])
euler[j] = j;
euler[j] = euler[j]/i*(i-1);
}
for(int i=2;i<=4000000;i++){
for(int j=1;i*j<=4000000;j++){
ans[i*j]+=j*euler[i];
}
}
for(int i=2;i<=4000000;i++)
ans[i]+=ans[i-1];
}
int main(){
int num;
getEuler();
while(cin>>num){
if(num==0)
break;
cout<<ans[num]<<endl;
}
return 0;
}