原题链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2421
题意就是给你一个n,让你求所有满足
1≤i<j≤n
的二元组的
gcd(i,j)
的和
可以观察到对任意
设则有进一步可以得到∑i=1i<jgcd(i,j)==gcd(i,j)≠1gcd(i,j)=tgcd(i/t,j/t)=1∑i|ji<j∑gcd(k,j/i)=1k<j/ii∑i|ji<jϕ(j/i)⋅i
也即我们可以先打个欧拉函数表,然后反过来枚举 gcd 的值,然后更新即可
#include <stdio.h>
#include<iostream>
#include<cmath>
#include<cstring>
const int Max=4000000;
using namespace std;
typedef long long LL;
int phi[Max+10];
LL ans[Max+10];
void init(){
for(int i=1;i<=Max;i++)phi[i]=i;
for(int i=2;i<=Max;i++){
if(phi[i]==i){
for(int j=i;j<=Max;j+=i){
phi[j]=phi[j]-phi[j]/i;
}
}
for(int j=1;i*j<=Max;j++)
ans[i*j]+=(LL)phi[i]*(LL)j;
}
for(int i=1;i<=Max;i++)ans[i]+=ans[i-1];
}
int main(void)
{
int n;init();
while(~scanf("%d",&n)&&n){
printf("%lld\n",ans[n]);
}
return 0;
}