http://www.spoj.com/problems/VLATTICE/en/
题意:
给一个长度为N的正方形,从(0,0,0)能看到多少个点。
思路:
这道题其实和能量采集是差不多的,只不过从二维上升到了三维。
分三部分计算:
①坐标值上的点,只有3个。
②与原点相邻的三个表面上的点,需满足gcd(x,y)=1。
③其余空间中的点,需满足gcd(x,y,z)=1。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<sstream> 6 #include<vector> 7 #include<stack> 8 #include<queue> 9 #include<cmath> 10 #include<map> 11 #include<set> 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int,int> pll; 15 const int INF = 0x3f3f3f3f; 16 const int maxn = 1000000 + 5; 17 18 bool check[maxn]; 19 int prime[maxn]; 20 int mu[maxn]; 21 ll sum[maxn]; 22 23 void Mobius() 24 { 25 memset(check, false, sizeof(check)); 26 mu[1] = 1; 27 int tot = 0; 28 for (int i = 2; i <= maxn; i++) 29 { 30 if (!check[i]) 31 { 32 prime[tot++] = i; 33 mu[i] = -1; 34 } 35 for (int j = 0; j < tot; j++) 36 { 37 if (i * prime[j] > maxn) 38 { 39 break; 40 } 41 check[i * prime[j]] = true; 42 if (i % prime[j] == 0) 43 { 44 mu[i * prime[j]] = 0; 45 break; 46 } 47 else 48 { 49 mu[i * prime[j]] = -mu[i]; 50 } 51 } 52 } 53 sum[0]=0; 54 for(int i=1;i<maxn;i++) 55 sum[i]=sum[i-1]+mu[i]; 56 return ; 57 } 58 59 ll compute1(int n) 60 { 61 ll tmp=0; 62 for(int i=1,last=0;i<=n;i=last+1) 63 { 64 last=n/(n/i); 65 tmp+=(sum[last]-sum[i-1])*(n/i)*(n/i)*(n/i); 66 } 67 return tmp; 68 } 69 70 ll compute2(int n) 71 { 72 ll tmp=0; 73 for(int i=1,last=0;i<=n;i=last+1) 74 { 75 last=n/(n/i); 76 tmp+=(sum[last]-sum[i-1])*(n/i)*(n/i); 77 } 78 return tmp; 79 } 80 81 int n, m; 82 83 int main() 84 { 85 //freopen("in.txt","r",stdin); 86 Mobius(); 87 int T; 88 scanf("%d",&T); 89 while(T--) 90 { 91 scanf("%d",&n); 92 printf("%lld\n",compute1(n)+compute2(n)*3+3); 93 } 94 return 0; 95 }