SP7001 VLATTICE - Visible Lattice Points 题解
无需用到莫比乌斯反演,可能是这个题最简单的做法了。
首先设每个点的坐标为
不难发现,这就相当于把题面中给定的正方体拆成很多层。
然后对于每一层进行讨论:
设
根据正方体公式可知第
对于点
所以第
观察到对于
可设
则对于
代码:
#include<stdio.h>
#define int long long
#define N 1000000
int n,ans[N+40];
signed main(){
for(int i=1;i<=N;++i){
ans[i]+=3*i*i+3*i+1;//注意是+=而非=,因为ans[i]在这之前可能被修改过
for(int j=i<<1;j<=N;j+=i)
ans[j]-=ans[i];
}
for(int i=1;i<N;++i)
ans[i+1]+=ans[i];
int T;scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
printf("%lld\n",ans[n]);
}
}
实际上这个做法可以方便的扩展到多维:
对于 ans[i]+=fpow(i+1,x)-fpow(i,x); 即可,其中 fpow 为快速幂。(当然有时也要取模)