题意:输入n,问所有gcd(i, j)的和,1<=i<j<=n,2<=n<=4000000
题解:可以发现是递推得到ans[n] = ans[n-1]+f[n],f[n]就代表了n和小于n的数的gcd的和,求f[n]可以由因子推得,枚举gcdb就是n的因子,gcd(n, a) = b所以gcd(n/b, a/b) = 1就是求与n/b互质的数有几个,也就是欧拉函数,这里用因子来推,每个因子对他的倍数都有贡献,预处理一下
#include <bits/stdc++.h> #define ll long long #define maxn 4000100 using namespace std; ll ans[maxn], f[maxn], phi[maxn]; void init(ll num){ for(int i=2;i<=num;i++) phi[i] = 0; phi[1] = 1; for(int i=2;i<=num;i++){ if(!phi[i]) for(int j=i;j<=num;j+=i){ if(!phi[j]) phi[j] = j; phi[j] = phi[j]/i*(i-1); } for(ll j=1;j*i<=num;j++) f[i*j] += phi[i]*j; } } int main(){ ll n; init(4000000); for(ll i=2;i<=4000000;i++) ans[i] = ans[i-1]+f[i]; while(~scanf("%lld", &n)&&n) printf("%lld ", ans[n]); return 0; }