bzoj 2818: Gcd

题目链接

bzoj 2818: Gcd

题解

对于一个素数p
我们可以求出n中有多少个他的倍数 \(k_xp\)
其中,若两数的系数\(k_x\)互质,那么这两数的gcd为素数p
对于一个素数p也就是求$\lfloor \frac{n}{p} \rfloor $中两两互素数的个数,欧拉函数前缀和就好了

代码

#include<cstdio>
#include<algorithm> 
const int maxn = 10000007; 
int prime[maxn],num; 
bool is_prime[maxn];long long phi[maxn]; 
void get_phi(int n ) { 
    is_prime[1] = true; 
    phi[1] = 1;
    for(int i = 2;i <= n;++ i) {
        if(!is_prime[i]) prime[++ num] = i,phi[i] = i - 1; 
        for(int j = 1;j <= num && prime[j] * i <= n;++ j) { 
            is_prime[i * prime[j]] = 1; 
            if(i % prime[j] == 0) { 
                phi[i *prime[j]] = phi[i] * prime[j]; 
                   break;   
            } 
            else phi[i * prime[j]] = phi[i] * (prime[j] - 1) ;  
        } 
    } 
} 
#define LL long long 
int main() {  
    int n; 
    scanf("%d",&n); 
    get_phi(n); 
        LL ans = 0;  
    int tmp = 0; 
    for(int i = 1;i <= n;++ i) phi[i] += phi[i - 1]; 
    for(int i = 1;i <= num;++ i) { 
        ans += 1ll*(phi[n / prime[i]] * 2 - 1);  
        //if(phi[n / prime[i]]) ans += phi[n / prime[i]] + 1; 
    }  
    printf("%lld\n",ans); 
    return 0; 
} 
posted @ 2018-06-08 19:26  zzzzx  阅读(244)  评论(0编辑  收藏  举报