7001. Visible Lattice Points

Problem code: VLATTICE

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 : 









 

Sample Output : 



19 

175 

 

Constraints : 

T <= 50 

1 <= N <= 1000000

题目大意

给定n*n*n的立方体,每一个整数点除(0。0。0)之外都有一盏灯(抽象理解),问能看到多少盏灯(被盖住的灯不算)

解题思路

莫比乌斯反演/容斥原理的典型应用

用容斥原理来解释就是三个点都能被k整除的个数乘上莫比乌斯系数,求和就可以

而三个点都能被k整除的个数就是floor(n/i)^3

注意到最大数据量为1000000 直接线性处理的办法可能TLE

而(n/i)在后面i>(n/2)的部分结果都为1 能够省去一次次计算,直接按mu的前缀和来处理

则我们就统计同样(n/i)的值是否出现两次。假设出现两次那么我们就開始依照前缀和的方法来处理

不优化 6200ms

优化后 490ms

code

优化前

#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 100000007ll
using 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;
}

优化后

#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
using 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 数论 莫比乌斯反演的更多相关文章

  1. SPOJ VLATTICE Visible Lattice Points(莫比乌斯反演)题解

    题意: 有一个\(n*n*n\)的三维直角坐标空间,问从\((0,0,0)\)看能看到几个点. 思路: 按题意研究一下就会发现题目所求为. \[(\sum_{i=1}^n\sum_{j=1}^n\su ...

  2. SPOJ—VLATTICE Visible Lattice Points(莫比乌斯反演)

    http://www.spoj.com/problems/VLATTICE/en/ 题意: 给一个长度为N的正方形,从(0,0,0)能看到多少个点. 思路:这道题其实和能量采集是差不多的,只不过从二维 ...

  3. SPOJ 7001. Visible Lattice Points (莫比乌斯反演)

    7001. Visible Lattice Points Problem code: VLATTICE Consider a N*N*N lattice. One corner is at (0,0, ...

  4. SPOJ 7001 VLATTICE - Visible Lattice Points(莫比乌斯反演)

    题目链接:http://www.spoj.com/problems/VLATTICE/ 题意:求gcd(a, b, c) = 1    a,b,c <=N 的对数. 思路:我们令函数g(x)为g ...

  5. SPOJ VLATTICE Visible Lattice Points (莫比乌斯反演基础题)

    Visible Lattice Points Consider a N*N*N lattice. One corner is at (0,0,0) and the opposite one is at ...

  6. Visible Lattice Points (莫比乌斯反演)

    Visible Lattice Points 题意 : 从(0,0,0)出发在(N,N,N)范围内有多少条不从重合的直线:我们只要求gcd(x,y,z) = 1; 的点有多少个就可以了: 比如 : 点 ...

  7. SPOJ VLATTICE Visible Lattice Points 莫比乌斯反演 难度:3

    http://www.spoj.com/problems/VLATTICE/ 明显,当gcd(x,y,z)=k,k!=1时,(x,y,z)被(x/k,y/k,z/k)遮挡,所以这道题要求的是gcd(x ...

  8. SPOJ VLATTICE Visible Lattice Points 莫比乌斯反演

    这样的点分成三类 1 不含0,要求三个数的最大公约数为1 2 含一个0,两个非零数互质 3 含两个0,这样的数只有三个,可以讨论 针对 1情况 定义f[n]为所有满足三个数最大公约数为n的三元组数量 ...

  9. SPOJ VLATTICE - Visible Lattice Points 【“小”大数加减】

    题目链接 一道比较简单的莫比乌斯反演,不过ans会爆long long,我是用结构体来存结果的,结构体中两个LL型变量分别存大于1e17和小于1e17的部分 #include<bits/stdc ...

随机推荐

  1. [SDOI2004]打鼹鼠

    ...... 心血来潮,手打abs 结果...BZOJ上CE,洛谷上WA... 把宏定义换成函数就过了 显然一个点可以走到另一个点,当且仅当两点鼹鼠出现时间$\leq$两点间距离的曼哈顿距离 显然是D ...

  2. Vue页面间传值,以及客户端数据存储

    初学Vue,遇到了页面传值的问题,大概网上学习了解了一下,在此跟大家分享一下学习心得,欢迎批评指正. 一.参数传值 如果是简单的页面传值,比如传一个id到详情页等等,推荐使用参数传值. 这里页面是通过 ...

  3. SQLServer2008 将“单个用户”改为“多用户”

    一开始是要想要分离掉数据库,然后将其删除 不知道为什么一直分离不了,试了很多次,又尝试直接删除 结果数据库突然显示成了“单个用户” 尝试查看其属性,或者“新建查询”也都报错,提示已经有其他用户建立了连 ...

  4. 配置 Sybase数据源

    1.Start-- > All Programs -- > Sybase - -> Connectivity --> click ‘Open Client Directory ...

  5. openMSP430之io_test

    openMSP430: IO functionality test with interupt #include "omsp_system.h" volatile char shi ...

  6. 本博客基本不再更新,请移步至我的CSDN博客

    本博客基本不再更新,请移步至我的CSDN博客:http://blog.csdn.net/wpxu08

  7. ubuntu操作系统的目录结构

    /:根目录,是所有目录的绝对路径的起始点.一般根目录下只存放目录,不要存放文件,/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中 /bin (类似的还有/usr/bin) ...

  8. 团体程序设计天梯赛-练习集-L1-044. 稳赢

    L1-044. 稳赢 大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示: 现要求你编写一个稳赢不输的程序,根据对方的出招,给出对应的赢招.但是!为了不让对方输得太惨,你需要每隔K ...

  9. matlab学习checkbox使用

    添加radiobutton1和checkbox2控件以及两个edittextbox控件 %得到控件的值var=get(handles.kj2,'value');%将数值显示到文本框中,将得到的数值转换 ...

  10. position:absolute与position:relative

    position的默认属性值均是static,静态. [position:absolute]定位为absolute的层脱离正常文本流,但其在正常流中的位置不再存在. 大多数人可能会觉得absolute ...