題意:
有一個邊長爲n的立方體,你位於(0,0,0)處,問能看見的格子數目。
某個格子能被看見當且僅當它與原點的連線上不存在其他的格子。
思路:
之前做過一個二維的版本:HDU2841 Visible Trees 莫比烏斯反演
思路是差不多的,分成三個部分求:
對於(x!=0&&y!=0&&z!=0)的所有點,要求 gcd(x,y,z)==1的點數
然後三個面上的點分別求gcd(x,y)==1 , gcd(x,z)==1 ,gcd(y,z)==1 的點數,很明顯每個面的點數是一樣多的。
最後加上三個位於軸上的點即可
代碼:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
vector<int>pr;
bool Np[N];
int sum[N];
void init(){
sum[1] = 1;
for(int i=2;i<N;i++){
if(!Np[i]){
sum[i] = -1;
pr.emplace_back(i);
}for(int j=0;j<pr.size();j++){
int t = pr[j] * i;
if(t>=N)break;
Np[t] = true;
if(i%pr[j]==0){
sum[t] = 0;
break;
}sum[t] = - sum[i];
}sum[i] += sum[i-1];
}
}
int main()
{
init();
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
long long ans = 3;
for(int i=1,last;i<=n;i=last+1){
last = n/(n/i);
ans += 1LL * (sum[last]-sum[i-1]) * (n/i) * (n/i) * ( (n/i) + 3 ) ;
}printf("%lld\n",ans);
}return 0;
}