POJ3090 Visible Lattice Points 欧拉筛
题目大意:给出范围为(0, 0)到(n, n)的整点,你站在原点处,问有多少个整点可见。
线y=x和坐标轴上的点都被(1,0)(0,1)(1,1)挡住了。除这三个钉子外,如果一个点(x,y)不互质,则它就会被点(x0, y0) (x0,y0互质,x/x0==y/y0)挡住。能看见的钉子关于线y=x对称。所以,求出x=2至n的所有与x互质的数的个数φ(x)的和(也就是线y=x右下角(因为φ(x)<x)所有能看见的点的个数)乘以2(对角线两旁的看见的点的个数)+3(那几个特殊点)即为所求。
求φ值时,利用下列性质:
- if n能整除以p,也能整除以p^2,则φ(n)=φ(n/p)*p
- if n能整除以p,但不能整除以p^2,则φ(n)=φ(n/p)*(p-1)。
这样,在线性求2至n的质数个数时将i当作n/p,prime[j]作为p,i*prime[j]作为n,(这样i%prime[j]就相当于n/p/p能否整除)同时更新以后的φ值即可。
#include <cstdio>
#include <cstring>
using namespace std; const int MAX_N = 1010; int v[MAX_N], prime[MAX_N], phi[MAX_N]; void Euler(int n)
{
int primeCnt = 0;
memset(v, 0, sizeof(v));
for (int i = 2; i <= n; i++)
{
if (!v[i])
{
prime[primeCnt++] = i;
v[i] = i;
phi[i] = i - 1;
}
for (int j = 0; j < primeCnt && prime[j] <= n / i && prime[j] <= v[i]; j++)
{
v[i * prime[j]] = v[i];
phi[i * prime[j]] = phi[i] * (i%prime[j] ? prime[j] - 1 : prime[j]);
}
}
} int main()
{
int n, testCase;
scanf("%d", &testCase);
for (int i = 1; i <= testCase; i++)
{
scanf("%d", &n);
Euler(n);
int ans = 0;
for (int j = 2; j <= n; j++)
ans += phi[j];
printf("%d %d %d\n", i, n, ans * 2 + 3);
}
return 0;
}
欧拉筛2:
void Euler(int *phi, int n)
{
static int prime[MAX_N];
static bool NotPrime[MAX_N];
int primeCnt=0;
memset(NotPrime,false,sizeof(NotPrime));
phi[1] = 1;
for(int i = 2; i <= n; i++)
{
if(!NotPrime[i])
{
prime[primeCnt++]=i;
phi[i] = i - 1;
}
for(int j=0; j < primeCnt; j++)
{
if(prime[j] * i > n)
break;
NotPrime[prime[j] * i] = true;
if(i % prime[j] == 0)
{
phi[prime[j] * i] = prime[j] * phi[i];
break;
}
else
phi[prime[j] * i] = (prime[j] - 1) * phi[i];
}
}
}
POJ3090 Visible Lattice Points 欧拉筛的更多相关文章
- POJ3090 Visible Lattice Points 欧拉函数
欧拉函数裸题,直接欧拉函数值乘二加一就行了.具体证明略,反正很简单. 题干: Description A lattice point (x, y) in the first quadrant (x a ...
- POJ 3090 Visible Lattice Points 欧拉函数
链接:http://poj.org/problem?id=3090 题意:在坐标系中,从横纵坐标 0 ≤ x, y ≤ N中的点中选择点,而且这些点与(0,0)的连点不经过其它的点. 思路:显而易见, ...
- POJ3090 Visible Lattice Points
/* * POJ3090 Visible Lattice Points * 欧拉函数 */ #include<cstdio> using namespace std; int C,N; / ...
- [poj 3090]Visible Lattice Point[欧拉函数]
找出N*N范围内可见格点的个数. 只考虑下半三角形区域,可以从可见格点的生成过程发现如下规律: 若横纵坐标c,r均从0开始标号,则 (c,r)为可见格点 <=>r与c互质 证明: 若r与c ...
- POJ3090 Visible Lattice Points (数论:欧拉函数模板)
题目链接:传送门 思路: 所有gcd(x, y) = 1的数对都满足题意,然后还有(1, 0) 和 (0, 1). #include <iostream> #include <cst ...
- [POJ3090]Visible Lattice Points(欧拉函数)
答案为3+2*∑φ(i),(i=2 to n) Code #include <cstdio> int T,n,A[1010]; void Init(){ for(int i=2;i< ...
- ACM学习历程—POJ3090 Visible Lattice Points(容斥原理 || 莫比乌斯)
Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal ...
- 数论 - 欧拉函数的运用 --- poj 3090 : Visible Lattice Points
Visible Lattice Points Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5636 Accepted: ...
- 【POJ】3090 Visible Lattice Points(欧拉函数)
Visible Lattice Points Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7705 Accepted: ...
随机推荐
- 证明,为什么HBase在创建表时,列簇是必须要,列可不要?
若是删除不存在的列修饰符,看下会是什么情况 package zhouls.bigdata.HbaseProject.Test1; import javax.xml.transform.Result; ...
- bitmap实现背景透明
近日在项目中,一直被一个问题搞得头大的很,美工要把按钮图片弄成不规则的,但是在winform里实现又不仅仅是使用简单的png图片而已.在网上找到一些方法,稍微改了一点加工成项目所需. 贴出解决方案,以 ...
- ubuntu 14.04安装x11VNC
环境:Ubuntu 14.04, 1)安装x11vnc: sudo apt-get install x11vnc 2)设置VNC的连接密码: x11vnc -storepasswd Enter VNC ...
- 如何将一个已有的项目托管到github或是码云上?git的配置
场景一:已有的一个项目,要把它托管到Git上去,步骤和方法如下: 方法一: ①在工程的路径下 : git init 建一个裸仓库. ②远程仓库地址 :将本地的仓库和远程仓库关联 git remote ...
- Js构造对象-添加方法的三种方式
Js构造函数添加方法有多种方案,来看一个混合方式构造函数的例子:申明person构造函数,有两个属性,name,qq.在原型上添加方法showname.这是最常用的方法. <script> ...
- Python这些问题你会吗?
inal作用域的代码一定会被执行吗? 正常的情况下,finally作用域的代码一定会被执行的,不管是否发生异常.哪怕是调用了sys.exit函数,finally也是会被执行的,那怎么样才能让final ...
- Java 8 函数接口详细教程
ay = new byte[array.length]; for (int i = 0; i < array.length; i++) { transformedArray[i] = funct ...
- Linux删除重复内容命令uniq笔记
针对文本文件,有时候我们需要删除其中重复的行.或者统计重复行的总次数,这时候可以采用Linux系统下的uniq命令实现相应的功能. 语法格式:uniq [-ic] 常用参数说明: -i 忽略大小写 - ...
- BZOJ 4278: [ONTAK2015]Tasowanie 后缀数组 + 贪心 + 细节
Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in", "r", stdin ...
- 【转载】java list的一些基本操作
1.list中添加,获取,删除元素 List<String> person=new ArrayList<>(); person.add("jackie"); ...