• POJ3090:Visible Lattice Points——题解


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

    题目大意:你站在(0,0)的点上看向第一向限的点,点和点会互相阻挡,问最多看到多少点。

    很容易想到,我们能看到的点,它的横纵坐标一定是互质的,那么怎么求呢?

    首先我们要知道一个东西叫做法雷级数:

    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,分子与n互质,所以加入了与n互质的数的个数。
    是不是欧拉函数啊(叫做E)
    所以Fn=Fn-1+En
    但是我们知道我们要求的F可以分子分母相反,那么实际我们求的是Fn*2-1(-1因为1/1)
    #include<cstdio>
    #include<cctype>
    #include<iostream>
    using namespace std;
    inline int read(){
        int X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    int f[1001],e[1001];
    bool h[1001];
    int p[1001],cnt=0;
    void Euler(int n){
        e[1]=1;
        for(int i=2;i<=n;i++){
        if(!h[i]){
            cnt++;
            p[cnt]=i;
            e[i]=i-1;
        }
        for(int j=1;j<=cnt&&i*p[j]<=n;j++){
            h[i*p[j]]=1;
            if(i%p[j]==0){
            e[i*p[j]]=e[i]*p[j];
            break;
            }
            e[i*p[j]]=e[i]*(p[j]-1);
        }
        }
        return;
    }
    void Farley(int n){
        f[1]=2;
        for(int i=2;i<=n;i++){
        f[i]=f[i-1]+e[i];
        }
        return;
    }
    int main(){
        Euler(1000);
        Farley(1000);
        int c=read();
        for(int i=1;i<=c;i++){
        int n=read();
        printf("%d %d %d
    ",i,n,f[n]*2-1);
        }
        return 0;
    }
  • 相关阅读:
    进入正在运行的Docker的asp.net core容器
    EF 更新记录发现外键更改但更新又跳回以前值
    远程获取http数据和提交数据
    C# 32位16进制加密
    netcore命令行运行程序
    MD5加密32位16进制
    C# MD5加密32位16进制有时少一位问题
    netcoreMVC中使用Vue模板分页封装(不适合数据量大)
    Vue组件间传值 和 访问
    jenkins部署安装
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/7898925.html
Copyright © 2020-2023  润新知