UVA11426 GCD - Extreme (II)
题目链接
\(T≤100\)
\(n≤40000000\)
解法一:莫比乌斯反演
打算用莫比乌斯反演水一发.
大概在
\(O(T*n*\sqrt{n})\)
UVA评测机真快,竟然过了.
#include <iostream>
#include <cstdio>
#define ll unsigned long long
const ll maxN= 40000000 + 7;
bool vis[maxN];
ll prime[maxN];
ll mu[maxN];
ll sum[maxN];
void init() {
ll num = 0;
vis[1] = 1;
mu[1] = 1;
for(ll i = 2;i <= 40000000;++ i) {
if( !vis[i] ) {
prime[++ num] = i;
mu[i] = -1;
}
for(ll j = 1;j <= num && prime[j] * i <= 40000000;++ j) {
vis[i * prime[j]] = true;
if(i % prime[j] == 0) {
mu[i * prime[j]] = 0;
break;
}
mu[i * prime[j]] = -mu[i];
}
}
for(ll i = 1;i <= 40000000;++ i)
sum[i] = sum[i - 1] + mu[i];
return;
}
ll slove(ll n,ll k) {
ll ans = 0;
n /= k;
for(ll l = 1,r;l <= n;l = r + 1) {
r = n / (n / l);
ans += ( sum[r] - sum[l - 1] ) * (n / l) * (n / l);
}
return ans;
}
int main() {
ll n = 1;
init();
while(scanf("%llu",&n) && n) {
ll ans = 0;
for(ll i = 1;i <= n;++ i)
ans += i * slove(n,i);
printf("%llu\n",(ans - (n + 1) * n / 2) / 2);
}
return 0;
}
解法2:利用phi
考虑每个数\(x\)被当做\(Gcd\)对答案的贡献.
\[GCD(i,j) = x
\]
转化成
\[GCD(i/x,j/x) == 1
\]
#include <iostream>
#include <cstdio>
const int maxN = 40000000 + 7;
int prime[7000000];
long long phi[maxN];
void init() {
int num = 0;
phi[1] = 1;
for(int i = 2;i < maxN;++ i) {
if( !phi[i] ) {
prime[++ num] = i;
phi[i] = i - 1;
}
for(int j = 1;j <= num && prime[j] * i < maxN;++ j) {
if(i % prime[j] == 0) {
phi[i * prime[j]] = phi[i] * prime[j];
break;
}
phi[i * prime[j]] = phi[i] *( prime[j] - 1);
}
}
for(int i = 2;i < maxN;++ i)
phi[i] += phi[i - 1];
return ;
}
int main() {
int fuck = 1;
int n;
init();
while(fuck) {
scanf("%d",&n);
if(!n) break;
long long sum = 0;
for(int i = 1;i < n;++ i) {
sum += ( phi[n / i] - 1 ) * i;
}
printf("%lld\n",sum);
}
return 0;
}