POJ-3090 Visible Lattice Points

本文详细介绍了如何使用法雷级数解决POJ网站上的一个二维点阵问题,通过枚举斜率并计算互质的数个数来找出可见点的数量,最后运用欧拉函数求解。

题目:

http://poj.org/problem?id=3090

题意:

就是给出一个二维点阵的大小,问从(0,0)点能看到的点的个数。

思路:

一开始最基本的思路就是枚举斜率,所有斜率相同的点是重复的,数据小就1e3,所以理论上那个可行。

之后发现所有能看到的点的斜率也就是分子分母互质的数,也就是所有真分数的个数。

后来知道这叫做法雷级数,像这样:

      F1: 0/1 1/1

  F2: 0/1 1/2 1/1

  F3: 0/1 1/3 1/2 2/3 1/1

  F4: 0/1 1/4 1/3 1/2 2/3 3/4 1/1

  F5: 0/1 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 1/1

  F6:0/1 1/6 1/5 1/4 1/3 2/5 1/2 3/5 2/3 3/4 4/5 5/6 1/1

然后就是法雷级数的求法。可以转换成求小于等于n的所有数i的小于等于i的与i互质的数的个数,比较绕口,简单地说就是求所有小于等于n的数的欧拉函数之和。

到这里就没问题了,直接套欧拉函数就行了。注意这样求出来的是斜率小于1的,还有对称的另一半,另外法雷级数还包括1/0,数论还是等练练,看能不能想到。

代码:

#define N 11234

long long  n,m;
long long eul[N],num[N];
void init()
{
     eul[1]=1;
     for(long long i=2;i<N;i++)
       eul[i]=i;
     for(long long i=2;i<N;i++)
        if(eul[i]==i)
           for(long long j=i;j<N;j+=i)
              eul[j]=eul[j]/i*(i-1);
    num[0]=0;
    for(int i=1;i<N;i++)
        num[i]=num[i-1]+eul[i];
}
int main()
{
    int i,j,k,kk,t,x,y,z;
    init();
    scanf("%d",&k);
    kk=0;
    while(k--)
    {
        scanf("%lld",&n);
        printf("%d %lld %lld\n",++kk,n,num[n]*2+1);
    }
    return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值