220. 最大公约数

// 220. 最大公约数.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//


/*
https://www.acwing.com/problem/content/222/

给定整数 N,求 1≤x,y≤N 且 GCD(x,y) 为素数的数对 (x,y) 有多少对。

GCD(x,y) 即求 x,y 的最大公约数。

输入格式
输入一个整数 N。

输出格式
输出一个整数,表示满足条件的数对数量。

数据范围
1≤N≤107
输入样例:
4
输出样例:
4
*/


#include <iostream>



using  namespace std;

const int N = 10000010;

int primes[N], cnt;     // primes[]存储所有素数
int euler[N];           // 存储每个数的欧拉函数
bool st[N];         // st[x]存储x是否被筛掉
long long pre[N];

void get_eulers(int n)
{
    euler[1] = 0;
    for (int i = 2; i <= n; i++)
    {
        if (!st[i])
        {
            primes[cnt++] = i;
            euler[i] = i - 1;
        }
        for (int j = 0; primes[j] <= n / i; j++)
        {
            int t = primes[j] * i;
            st[t] = true;
            if (i % primes[j] == 0)
            {
                euler[t] = euler[i] * primes[j];
                break;
            }
            euler[t] = euler[i] * (primes[j] - 1);
        }
    }
    for (int i = 1; i <= n; i++) {
        pre[i] = pre[i - 1] + euler[i];
    }

}


void solve(int x) {
    long long res = 0;
    for (int i = 0; i < cnt; i++) {
        int p = primes[i];
        if (p > x) break;
        res += pre[x/p] * 2 + 1;
    }

    cout << res << endl;
}
 

int main()
{
    int n; cin >> n;
    get_eulers(n);
    solve(n);

    return 0;
}

posted on 2025-03-20 14:19  itdef  阅读(12)  评论(0)    收藏  举报

导航