POJ 2478 Farey Sequence & POJ 3090 Visible Lattice Points (欧拉函数)

POJ 2478 题意:给定一个数n,求小于或等于n的数中两两互质组成的真分数的个数。

POJ 3090 题意:一个(0, n)*(0, n)的图,从点(0,0)到点(x,y)画线段不经过其它点,问能画多少条。


思路:

POJ3090

1×1只有一个斜率为0的
2×2斜率有0,1/2(0已经算过了,以后不再算了),其实就多了一个斜率为1/2的。
3×3的时候,有1/3,2/3两个,比以前多了2个
4×4的时候,有1/4,2/4(1/2已经有过了),3/4,所以也是2个
5×5的时候,有1/5,2/5,3/5,4/5,之前都没有,所以多了4个
6×6得到时候,有1/6,2/6(1/3已经有了),3/6(1/2已经有了),4/6(2/3已经有了),5/6,所以只剩2个。

分子和分母能够约分的,前面都已经有过了,所以每次要加的个数就是分子和分母互质的个数,也就是欧拉函数

(POJ2478同理)


POJ3090代码:

#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn = 1e3+5;
int phi[maxn], p[maxn], pNum;
bool f[maxn];
int sum[maxn];

void init()
{
    for(int i = 2; i < maxn; i++)
    {
        if(!f[i])
        {
            p[pNum++] = i;
            phi[i] = i-1;
        }
        for(int j = 0; j < pNum && p[j]*i < maxn; j++)
        {
            f[p[j]*i] = 1;
            if(i%p[j] == 0)
            {
                phi[p[j]*i] = phi[i]*p[j];
                break;
            }
            else
                phi[p[j]*i] = phi[i]*(p[j]-1);
        }
    }
}

int main(void)
{
    init();
    phi[1] = 1;
    for(int i = 1; i < maxn; i++)
        sum[i] = sum[i-1]+phi[i];
    int t, ca = 1;
    cin >> t;
    while(t--)
    {
        int x;
        scanf("%d", &x);
        printf("%d %d %d\n", ca++, x, sum[x]*2+1);//加1是对角线,*2是对称的上面的三角形
    }
    return 0;
}


你可能感兴趣的:(数学)