《算法竞赛进阶指南》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

代码:

#include
#include
#include
#include
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){
            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<//        if((i-1)%10 == 0 && i-1)cout<//    }
    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\n",++T,n,3+2*sum[n]);
    } 
} 

 

你可能感兴趣的:(《算法竞赛进阶指南》0x32欧拉函数 POJ3090 Visible Lattice Points)