Coding Test/BaekJoon_C++

백준 23832 <서로소 그래프> C++

JunOnJuly 2024. 4. 1. 20:52
728x90

https://www.acmicpc.net/problem/23832

 

23832번: 서로소 그래프

우석이는 심심할 때마다 그래프를 그린다. 우석이는 매달 새로운 그래프를 그리는데, 이번 달에는 서로소 그래프를 그린다. 서로소 그래프는 $1$부터 $N$까지의 번호를 가진 $N$ 개의 정점으로 이

www.acmicpc.net


오일러 피 함수 정의에 따라 풀어주면 됩니다.

 

오일러 피 함수 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 오일러 파이 함수의 그래프. ϕ(1)부터 ϕ(1000)까지의 값들을 나타낸다. 수론에서 오일러 파이 함수(-函數, 영어: Euler’s phi (totient) function)는 정수환의 몫환의 가

ko.wikipedia.org


#include <iostream>
#include <array>
#include <vector>
#include <algorithm>

using namespace std;

int main(void) {
    // 입력
    int N;
    cin >> N;

    // 수 목록
    array<bool, 50001> nums;
    nums.fill(true);
    // 소인수 목록
    array<vector<int>, 50001> factors;
    // 순회
    for (int i = 2; i < N / 2 + 1; i++) {
        // 현재 수가 true 일 때, 앞선 수의 배수가 아닐 때
        if (nums[i]) {
            // 현재 수의 배수 체크
            for (int j = 2 * i; j < N + 1; j += i) {
                nums[j] = false;
                // 소인수 목록에 넣기
                factors[j].push_back(i);
            }
        }
    }

    // 오일러 피 함수에 따라
    // pi(소수) = 소수 - 1
    // pi(소수가 아닌 수) = 소수가 아닌 수 * ( (1 - 1/소인수) 들의 곱 )
    // 간선들의 합
    long long int sum_edges = 0;
    // 순회, i = 1 인 경우는 카운트하지 않음
    for (int i = 2; i < N + 1; i++) {
        // 소수면
        if (nums[i]) sum_edges += i - 1;
        // 아니면
        else {
            int add_num = i;
            for (auto factor : factors[i]) {
                add_num *= (factor - 1);
                add_num /= factor;
            }
            sum_edges += add_num;
        }
    }

    cout << sum_edges;
}

 

728x90

'Coding Test > BaekJoon_C++' 카테고리의 다른 글

백준 5719 <거의 최단 경로> C++  (0) 2024.04.04
백준 2325 <개코전쟁> C++  (0) 2024.04.03
백준 1797 <균형잡힌 줄서기> C++  (1) 2024.03.31
백준 15554 <전시회> C++  (2) 2024.03.29
백준 1162 <도로포장> C++  (0) 2024.03.28