题目链接
https://projecteuler.net/problem=530
Solution
推式子+欧拉反演
[egin{aligned}
ans&=sum_{i=1}^{n}sum_{jmid i}gcd(j,frac{i}{j})\
&=sum_{i=1}^{sqrt n}sum_{jmid i}sum_{kmid j,kmid frac{i}{j}}varphi(k)\
&=sum_{k=1}^{sqrt n}varphi(k)sum_{k|i,k|j}[ijle n]\
&=sum_{k=1}^{sqrt n}varphi(k)sum_{i,jge 1}[ijle frac{n}{k^2}]\
&=sum_{k=1}^{sqrt n}varphi(k)sum_{i=1}^{frac{n}{k^2}}lfloorfrac{frac{n}{k^2}}{p}
floor
end{aligned}
]
然后就大力求就好了。再算一下复杂度:
[egin{aligned}
T(n)&=sqrt n imes sum_{k=1}^{sqrt n} k^{-1}\
&=sqrt n imes lnsqrt n
end{aligned}
]
大概可以在 ([1s,10s]) 之间内得出答案。
然后我的程序跑了13s
这里是跑了3013s的code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int MAXN=300005;
const ll mod=1e9+7;
const ll inv2=mod-mod/2;
const ll inv6=166666668;
template <typename T>
void read(T &x) {
T flag=1;
char ch=getchar();
for (; '0'>ch||ch>'9'; ch=getchar()) if (ch=='-') flag=-1;
for (x=0; '0'<=ch&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
x*=flag;
}
ll a, b;
ll prime[40000005], phi[40000005];
int cnt;
bool mark[40000005];
int T;
ll n;
void sieve() {
phi[1]=1;
for (int i=2; i<=40000000; i++) {
if (!mark[i]) {
prime[++cnt]=i;
phi[i]=i-1;
}
for (int j=1; j<=cnt&&prime[j]*i<=40000000; j++) {
mark[prime[j]*i]=true;
if (i%prime[j]==0) {
phi[i*prime[j]]=phi[i]*prime[j];
} else {
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
}
int main() {
sieve();
read(n);
ll x=sqrt(n), ans=0;
for (ll i=1; i<=x; i++) {
ll lim=n/(i*i);
for (ll j=1, k; j<=lim; j=k+1) {
k=lim/(lim/j);
ans+=phi[i]*(k-j+1)*(lim/j);
}
}
printf("%lld
", ans);
return 0;
}