[bzoj2818]: Gcd

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bzoj2818]: Gcd相关的知识,希望对你有一定的参考价值。

想了一下就秒了

大概算是欧拉函数里比较好想的题了

直接考虑$gcd(x,y) = 1$

因为互质就满足性质$gcd(x * p,y * p) = p$

所以就可以转化成欧拉函数了,就是求出互质对数然后对合法的素数匹配一下就行了

可以用前缀和优化

 

对于质数的处理我是直接在求欧拉函数的时候筛的

所以复杂度是$O(nloglogn)$的,但是不开O2貌似跑不过

楼下几位dalao的复杂度我不是很会算,不知道有没有dalao能解释一下

#include <cstdio>
#include <ctype.h>
#include <cstdlib>

#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

template <typename T>
inline T read(T &f){
    f = 0;
    int x = 1;
    char c = getchar();
    while(!isdigit(c)){
        if(c == -)
            x = -1;
        c = getchar();
    }
    while(isdigit(c))
        f = (f << 1) + (f << 3) + c - 0,c = getchar();
    return f = f * x;
}

#define LL long long

const int maxn = 10000000 + 5;

int n,tot;

LL S[maxn];
LL pri[maxn],phi[maxn];

LL ans;

void phi_table(){
    phi[1] = 1;
    for(int i = 2;i <= n;i ++)
        if(!phi[i]){
            pri[++ tot] = i;
            for(int j = i;j <= n;j += i){
                if(!phi[j]) phi[j] = j;
                phi[j] = phi[j] / i * (i - 1);
            }
        }
}

int main(){
    read(n);
    
    phi_table();

    for(int i = 1;i <= n;i ++)
        S[i] = S[i - 1] + phi[i];
    
    for(int i = 1;i <= tot;i ++)
        ans = ans + (S[n / pri[i]] << 1) - 1;

    printf("%lld\n",ans);
    return 0;
}

 

以上是关于[bzoj2818]: Gcd的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2818 Gcd(莫比乌斯反演)

bzoj 2818: Gcd

BZOJ2818 Gcd

BZOJ-2818Gcd 线性筛

BZOJ 2818: Gcd

bzoj 2818 Gcd