admin管理员组文章数量:1516870
Spoj 7001 Visible Lattice Points 莫比乌斯,分块
题目:.action?id=37193 Visible Lattice Points| Time Limit: 1368MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu |
Submit Status
Description
Consider a N*N*N lattice. One corner is at (0,0,0) and the opposite one is at (N,N,N). How many lattice points are visible from corner at (0,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
Hint
题意:在一个边长为n的正方体内,从原点出发能够接触多少个点。 题解: 莫比乌斯反演。 首先,我们要把答案分三类讨论: 1, 坐标轴上的三个点可以看见(1,0,0)和(0,1,0)和(0,0,1)。 2, 与原点相邻的三个表面的点。在三个表面各反演一次,加起来即可。 3, 在三维空间中反演一次即可。 答案为三种情况的和。 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define MAXN 1000010
4 #define LL long long
5 int mu[MAXN+10],prime[80010],qz[MAXN+10],tot;
6 bitset<MAXN+10> vis;
7 int read()
8 {
9 int s=0,fh=1;char ch=getchar();
10 while(ch<'0'||ch>'9'){if(ch=='-')fh=-1;ch=getchar();}
11 while(ch>='0'&&ch<='9'){s=s*10+(ch-'0');ch=getchar();}
12 return s*fh;
13 }
14 void getmu()
15 {
16 int i,j;
17 mu[1]=1;tot=0;
18 for(i=2;i<=MAXN;i++)
19 {
20 if(vis[i]==0)
21 {
22 prime[++tot]=i;
23 mu[i]=-1;
24 }
25 for(j=1;j<=tot&&prime[j]*i<=MAXN;j++)
26 {
27 vis[prime[j]*i]=1;
28 if(i%prime[j]==0)
29 {
30 mu[prime[j]*i]=0;
31 break;
32 }
33 mu[prime[j]*i]=-mu[i];
34 }
35 }
36 }
37 void Qz()
38 {
39 for(int i=1;i<=MAXN;i++)qz[i]=qz[i-1]+mu[i];
40 }
41 LL calc2(int n)//计算平面上的个数.
42 {
43 int d,pos;
44 LL sum=0;
45 for(d=1;d<=n;d=pos+1)
46 {
47 pos=n/(n/d);
48 sum+=(LL)(qz[pos]-qz[d-1])*(n/d)*(n/d);
49 }
50 return sum;
51 }
52 LL calc3(int n)//计算空间里的个数.
53 {
54 int d,pos;
55 LL sum=0;
56 for(d=1;d<=n;d=pos+1)
57 {
58 pos=n/(n/d);
59 sum+=(LL)(qz[pos]-qz[d-1])*(n/d)*(n/d)*(n/d);
60 }
61 return sum;
62 }
63 int main()
64 {
65 int N,T;
66 T=read();
67 getmu();
68 Qz();
69 while(T--)
70 {
71 N=read();
72 printf("%lld\n",calc3(N)+calc2(N)*3+3);
73 }
74 fclose(stdin);
75 fclose(stdout);
76 return 0;
77 } View Code
转载于:.html
本文标签: Spoj 7001 Visible Lattice Points莫比乌斯分块
版权声明:本文标题:Spoj 7001 Visible Lattice Points莫比乌斯,分块 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.betaflare.com/biancheng/1709372129a757620.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。


发表评论