题目链接: poj3090
题目大意:对于二维坐标系中的点{(x,y)(0 <= x <= N, 0 <= y <= N)},问这些点中有哪些是原点可以看到的。(原点除外)
题目可以转化为求gcd(x, y) == 1 的有序对(x, y)的数目。
这道题数据范围较小,并且是求x,y互质的数的个数,我们可以采用多种方法来解决。
解法1.欧拉函数
若加一个限制条件:x < y,这其实就是求欧拉函数φ。它的定义是小于等于i的所有与i互质的数的个数。
那么在求出欧拉函数后,乘2就是所有的gcd(x, y) == 1的值了。不过在y = 1时,x和y相等,不用乘2.
另外,这样求的实际上是 1 <= x <= N, 1 <= y <= N的所有情况,还要加上x或y等于0的情况。
欧拉函数可以通过Euler筛法线性得到。
|
|
解法2.dp
这道题还可以通过dp来解决。其实dp的主要思想和mobius反演相同。我们考虑如下定义的F(d)和f(d):
f(d) = | {(x, y) | gcd(x, y) == d}, x <= N, y <= N} |
F(d) = | {(x, y) | (d | gcd(x, y)), x <= N, y <= N} |
F(d)我们可以很容易求出,它就等于(N / d) × (N / d),那么如何通过F(d)求出f(d)呢?
我们再来看看F(d)和f(d)的定义,f(d)代表x和y的最大公约数等于d的个数,F(d)表示x和y的公约数(不一定最大)等于d的个数。那么将F(d)中最大公约数大于d的所有个数去掉就是f(d)了。因此我们可以通过枚举d的倍数求出
f(d) = F(d) - f(2d) - f(3d) - ……
根据调和级数的性质,这个可以在O(nlogn)的时间复杂度内完成。我们要求的其实就是f(1)。
|
|
解法3.mobius反演
此外,我们还可以通过mobius反演来求出gcd(x, y) == 1的个数。首先,我们考虑如上含义的f(d), F(d),则有
,
反演得
同时还有F(d) = (N / d) × (N / d),代入反演后的式子则有
而我们要求的就是f(1)。
|
|