AcWing220-最大公约数

给定整数 N N N ,求 1 ≤ x , y ≤ N 1≤x,y≤N 1x,yN G C D ( x , y ) GCD(x,y) GCD(x,y) 为素数的数对 ( x , y ) (x,y) (x,y) 有多少个

考虑 1 1 1~ N N N 内的每个质数 p i p_i pi, 都有 gcd ⁡ ( x , y ) = p i \gcd(x, y) = p_i gcd(x,y)=pi
对该式化简有 gcd ⁡ ( x p i , y p i ) = 1 \gcd(\frac{x}{p_i} , \frac{y}{p_i}) = 1 gcd(pix,piy)=1
不妨设 1 ≤ x < y ≤ N 1 \leq x < y \leq N 1x<yN,而 y < x y < x y<x 的情况仅需要乘 2 2 2 即可
那么对每个 p i p_i pi 1 ≤ x p i < y p i ≤ N p i 1 \leq \frac{x}{p_i} < \frac{y}{p_i} \leq \frac{N}{p_i} 1pix<piypiN
也就是说,对每个 y p i \frac{y}{p_i} piy 我们要求与他互质的个数,即对每个 p i p_i pi ∑ j = 1 ⌊ N p i ⌋ φ ( j ) \sum\limits_{j = 1} ^{\lfloor \frac{N}{p_i}\rfloor} \varphi(j) j=1piNφ(j)
再去想当 j = 1 j = 1 j=1 的时候,也就是 y = p i y = p_i y=pi,此时也必然有 x = p i x = p_i x=pi,而两个相等的数只能算一种,因此最后答案 ∑ i = 1 c n t p ( 2 × ∑ j = 1 ⌊ N p i ⌋ φ ( j ) − 1 ) \sum\limits_{i = 1} ^{cntp} (2 \times \sum\limits_{j = 1} ^{\lfloor \frac{N}{p_i}\rfloor} \varphi(j) - 1) i=1cntp(2×j=1piNφ(j)1)
对于后一个和式可用前缀和在 O ( n ) O(n) O(n) 内算出

CODE
#include <iostream>
#define ll long long

using namespace std;

const int maxn = 1e7 + 10;

int npri[maxn];
int pri[maxn], eurl[maxn];
ll sum[maxn];
int cntp = 0;


void geteurl(int n){
    eurl[1] = 1;
    for (int i = 2; i <= n; i++){
        if (!npri[i]){
            pri[++cntp] = i;
            eurl[i] = i - 1;
        }
        for (int j = 1; i * pri[j] <= n; j++){
            npri[pri[j] * i] = 1;
            if (i % pri[j] == 0){
                eurl[i * pri[j]] = eurl[i] * pri[j];
                break;
            }
            eurl[i * pri[j]] = eurl[i] * (pri[j] - 1);
        }
    }
}


int main(){
    geteurl(maxn);
    for (int i = 1; i <= maxn; i++) sum[i] = sum[i - 1] + eurl[i];
    int n;
    cin >> n;
    ll ssum = 0;
    for (int i = 1; i <= cntp; i++){
        if (pri[i] > n) break; 
        ssum += 2 * sum[n / pri[i]] - 1;
    }
    cout << ssum;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值