## Tuesday

https://yukizzz.github.io/

# SPOJ 7001 VLATTICE【莫比乌斯反演】

## 题目链接：

http://www.spoj.com/problems/VLATTICE/

## 题意：

1x,y,zn$1\le x,y,z \le n$，问有多少对(x,y,z)$(x,y,z)$使得gcd(x,y,z)=1$gcd(x,y,z)=1$

## 分析：

f(d)$f(d)$：满足gcd(x,y,z)=d$gcd(x,y,z)=d$x,y,z$x,y,z$均在给定范围内的(x,y,z)$(x,y,z)$的对数。
F(d)$F(d)$：满足d|gcd(x,y,z)$d|gcd(x,y,z)$x,y,z$x,y,z$均在给定范围内的(x,y,z)$(x,y,z)$的对数。

f(x)=x|dμ(d/x)[n/d][n/d][n/d]

## 代码：

/*
-- SPOJ 7001
-- mobius
-- Create by jiangyuzhu
-- 2016/5/30
*/
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <stack>
using namespace std;
typedef long long ll;
#define sa(n) scanf("%d", &(n))
#define sal(n) scanf("%I64d", &(n))
#define pl(x) cout << #x << " " << x << endl
#define mdzz cout<<"mdzz"<<endl;
const int maxn = 1e6 + 5 ;
int tot = 0;
int miu[maxn], prime[maxn], f[maxn];
bool flag[maxn];
void mobius()
{
miu[1] = 1;
tot = 0;
for(int i = 2; i < maxn; i++){
if(!flag[i]){
prime[tot++] = i;
miu[i] = -1;
}
for(int j = 0; j < tot && i * prime[j] < maxn; j++){
flag[i * prime[j]] = true;
if(i % prime[j]) miu[i * prime[j]] = -miu[i];
else{
miu[i * prime[j]] = 0;
break;
}
}
}
}
int main (void)
{
mobius();
int T;sa(T);
int n;
for(int kas = 1; kas <= T; kas++){
scanf("%d", &n);
ll ans = 3;
for(int i = 1; i <= n; i++){
ans += miu[i] * 1ll * (n/ i) * (n / i) * (n / i + 3);
}
printf("%lld\n", ans);
}
return 0;
}


04-19 196

12-31 550

08-17 814

07-14 155

04-29 376

10-06 2841

08-03 214

08-11 95

10-31 265

07-30 757