zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x32欧拉函数 POJ3090 Visible Lattice Points

    题目链接:http://poj.org/problem?id=3090

    从(0,0)向周围看去,能在(N,N)点以内看到的点的个数,假设x,y不是互质的,那么一定存在一个点(x/d,y/d)在(x,y)前面被看到,所以看到的点的x和y 一定是互质的,我们只需要扫描一遍n>=y>x.=2中的y就可以,对于一个y我们只要知道2<=x<y中有多少个数是跟它互质的,就是欧拉函数的前缀和,可以在O(N)时间内用最小质数筛法求出来。最后再对称回去就可以了。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    using namespace std;
    #define maxn 1010
    int sum[maxn],phi[maxn];
    int n;
    int v[maxn];
    vector<int> prime;
    void get_prime(int n){
        memset(v,0,sizeof(v));
        for(int i=2;i<=n;i++){
            if(!v[i]){
                v[i]=i;prime.push_back(i);
                phi[i]=i-1;
            }
            for(int j=0;j<prime.size();j++){
                if(prime[j]>v[i] || prime[j]>n/i )break;
                v[i*prime[j]]=prime[j];
                //当p|n 且p^2|n时,phi[n]=phi[n/p]*p
                //当 当p|n 且p^2不能整除n时,phi[n]=phi[n/p]*(p-1)
                phi[i*prime[j]] = phi[i]* (i%prime[j]?prime[j]-1:prime[j]);
            }
        }
    }
    int main(){
        get_prime(1008);
        
    //    for(int i=1;i<=100;i++){
    //        cout<<phi[i]<<" ";
    //        if((i-1)%10 == 0 && i-1)cout<<endl;
    //    }
        for(int i=2;i<1008;i++)sum[i]=sum[i-1]+phi[i];
        int T=0,num;
        cin>>num;
        while(num--){
            scanf("%d",&n);
            printf("%d %d %d
    ",++T,n,3+2*sum[n]);
        } 
    } 
  • 相关阅读:
    LInux SSH远程文件/目录传输命令scp(转载)
    Linux系统时间设置(转载)
    Linux重置mysql密码(转载)
    快速输入(简单版)
    bitset
    或 、与、异或
    bitset
    Java面向对象3(K~O)
    Java面向对象2(G~J)
    数据结构实验之栈与队列六:下一较大值(二)(SDUT 3333)
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13180203.html
Copyright © 2011-2022 走看看