Visible Lattice Points
题意 : 从(0,0,0)出发在(N,N,N)范围内有多少条不从重合的直线;我们只要求gcd(x,y,z) = 1; 的点有多少个就可以了;
比如 : 点(2,4,6)可以等价成(1,2,3)即经过(1,2,3)的线一定经过(2,4,6);
莫比乌斯反演的模板题, 由于点坐标可以为0 , 需要考虑 x, y, z 中两个为0 和一个为0 的情况 :
两个为0 时 : 有 三个点(在x , y, z 轴上); 一个为0 时 : mu[i] * (n/i) * (n/i) * 3;
即 : mu[i] * (n/i) * (n/i)* (n/i+3) + 3;
#include<iostream> #include<cstring> using namespace std; #define ll long long const int maxn = 1000005; ll mu[maxn], pri[maxn], T, cnt, vis[maxn]; void init() { memset(vis, 0 , sizeof(vis)); memset(mu,0,sizeof(mu)); mu[1] = 1; cnt = 0; ll n = 1000005; for(ll i = 2; i <= n; i++) { if(!vis[i]) { mu[i] = -1; pri[cnt++] = i; } for(ll j = 0; j < cnt&&i*pri[j] <= n; j++) { ll k = i*pri[j]; vis[k] = 1; if(i%pri[j] == 0) {mu[k] = 0; break;} else mu[k] = -mu[i]; } } } int main() { // ios::sync_with_stdio(false); init(); cin >> T; while(T--) { ll n; cin >> n; ll ans = 3; for(ll i = 1; i <= n; i++) ans += (ll)(mu[i] * (n/i) * (n/i)* (n/i+3)); cout << ans << endl; } return 0; }