[SPOJ7001]VLATTICE - Visible Lattice Points
题目大意:
$q(q\leq50)$组询问,对于给定的$n(n\leq10^7)$,求$\displaystyle\sum_{i=0}^n\sum_{j=0}^n\sum_{k=0}^n[\gcd(i,j,k)=1]$。
思路:
$原式=\sum_{d=1}^n(\lfloor\frac{n}{d}\rfloor^3+3\lfloor\frac{n}{d}\rfloor^2+3\lfloor\frac{n}{d}\rfloor)\mu(d)$。数论分块即可。
1 #include<cstdio> 2 #include<cctype> 3 typedef long long int64; 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 const int N=10000001,M=664580; 12 bool vis[N]; 13 int mu[N],sum[N],p[M]; 14 inline void sieve() { 15 mu[1]=1; 16 for(register int i=2;i<N;i++) { 17 if(!vis[i]) { 18 p[++p[0]]=i; 19 mu[i]=-1; 20 } 21 for(register int j=1;j<=p[0]&&i*p[j]<N;j++) { 22 vis[i*p[j]]=true; 23 if(i%p[j]==0) { 24 mu[i*p[j]]=0; 25 break; 26 } else { 27 mu[i*p[j]]=-mu[i]; 28 } 29 } 30 } 31 for(register int i=1;i<N;i++) { 32 sum[i]=sum[i-1]+mu[i]; 33 } 34 } 35 int main() { 36 sieve(); 37 for(register int T=getint();T;T--) { 38 const int n=getint(); 39 int64 ans=0; 40 for(register int i=1,j;i<=n;i=j+1) { 41 j=n/(n/i); 42 ans+=(sum[j]-sum[i-1])*((int64)(n/i)*(n/i)*(n/i)+(int64)(n/i)*(n/i)*3+(n/i)*3); 43 } 44 printf("%lld\n",ans); 45 } 46 return 0; 47 }
原式=\sum_{d=1}^n(\lfloor\frac{n}{d}\rfloor^3+3\lfloor\frac{n}{d}\rfloor^2+3\lfloor\frac{n}{d}\rfloor)\mu(d)$。数论分块即可。