7001. Visible lattice pointsproblem code: vlattice |
Consider a n * n lattice. one corner is at (0, 0) and the opposite one is at (N, N, N ). how many lattice points are visible from corner at (0, 0 )? A point X is visible from point y IFF no other lattice point lies on the segment joining X and Y.
Input:
The first line contains the number of test cases T. The next t lines contain an interger n
Output:
Output t lines, one corresponding to each test case.
Sample input:
3
1
2
5
Sample output:
7
19
175
Constraints:
T <= 50
1 <= n <= 1000000
Theme
Given a cube of N * n, each integer point has a lamp (abstract understanding) except (0, 0, 0 ), how many lights can be seen? (the covered lights are not counted)
Solutions
Typical application of Mobius Inversion/rejection Principle
The principle of rejection is that all three vertices can be multiplied by the number of vertices divisible by K by the Mobius coefficient, and the sum is enough.
The number of all three vertices that can be divisible by K is floor (N/I) ^ 3.
Note that the maximum data volume is 1000000 direct linear processing possible TLE
However, some results of (N/I) in I> (n/2) below can all be calculated once and again, and are processed by the Mu prefix and
Then, we will count whether the same (N/I) value appears twice. If it appears twice, we will start to process it by prefix and method.
6200 MS not optimized
After optimization, 490 Ms
Code
Before Optimization
#include <cstdio>#include <iostream>#include <algorithm>#include <ctime>#include <cctype>#include <cmath>#include <string>#include <cstring>#include <stack>#include <queue>#include <list>#include <vector>#include <map>#include <set>#define sqr(x) ((x)*(x))#define LL long long #define INF 0x3f3f3f3f#define PI acos(-1.0)#define eps 1e-10#define mod 100000007llusing namespace std;LL n;LL com[1000005],pri[1000005],phi[1000005],pn,sum[1000005],mu[1000005];LL a[1000005];int main(){ memset(com ,0 ,sizeof com); mu[1]=1; for (int i=2;i<=1000000ll;i++) { if (com[i]==0) { phi[i]=i-1; pri[++pn]=i; mu[i]=-1; // printf("%d\n", pri[pn]); // system("pause"); } for (int j=1;j<=pn&&pri[j]*i<=1000000ll;j++) { if (i%pri[j]) { phi[i*pri[j]]=phi[i]*(pri[j]-1); com[i*pri[j]]=1; mu[i*pri[j]]=-mu[i]; } else { phi[i*pri[j]]=phi[i]*(pri[j]); com[i*pri[j]]=1; mu[i*pri[j]]==0; break; } } } sum[0]=0; for (int i=1;i<=1000000ll;i++) sum[i]=sum[i-1]+phi[i]; int T; scanf("%d",&T); while (T--) { // n=1000000; LL ans=0; scanf("%lld",&n); for (int i=n;i;i--) { a[i]=(n/i)*(n/i)*(n/i); ans+=a[i]*mu[i]; } printf("%lld\n",ans+(sum[n]*2+1)*3+3); } return 0;}
After Optimization
#include <cstdio>#include <iostream>#include <algorithm>#include <ctime>#include <cctype>#include <cmath>#include <string>#include <cstring>#include <stack>#include <queue>#include <list>#include <vector>#include <map>#include <set>#define sqr(x) ((x)*(x))#define LL long long #define INF 0x3f3f3f3f#define PI acos(-1.0)#define eps 1e-10using namespace std;int mu[1000005];int com[1000005];int pri[1000005],pn=0;int phi[1000005];LL presum[1000005];int musum[1000005];int main(){memset(com,0,sizeof com);presum[1]=0;mu[1]=1;phi[1]=0;for (int i=2;i<=1000000;i++) { if (com[i]==0) { pri[++pn]=i; mu[i]=-1; phi[i]=i-1; } for (int j=1;j<=pn&&pri[j]*i<=1000000;j++) { if (i%pri[j]) { mu[i*pri[j]]=-mu[i]; com[i*pri[j]]=1; phi[i*pri[j]]=phi[i]*(pri[j]-1); } else { phi[i*pri[j]]=phi[i]*(pri[j]); mu[i*pri[j]]=0; com[i*pri[j]]=1; break; } } presum[i]=presum[i-1]+phi[i]; musum[i]=musum[i-1]+mu[i]; } int T; scanf("%d",&T); int a,b,c,d,k; while (T--) { int n; LL ans=0; scanf("%d",&n); int i; for (i=1;i<=n;i++) if ((n/i)==(n/(i+1))) break; else ans+=(LL)(n/i)*(n/i)*(n/i)*mu[i]; for (int j=(n/i);j;j--) ans+=(LL)(j)*(j)*(j)*(musum[n/(j)]-musum[n/(j+1)]); ans+=(LL)presum[n]*6+6; printf("%lld\n",ans); } return 0;}
[Spoj vlattice] visible lattice points Number Theory Mobius Inversion