Skip to content

Latest commit

 

History

History
60 lines (45 loc) · 1.62 KB

File metadata and controls

60 lines (45 loc) · 1.62 KB

문제

제곱 ㄴㄴ 수

문제 원본

문제의 원본은 여기서 확인하세요.

분류

  • 에라토스테네스의 체

풀이

에라토스테네스의 체를 이용하여 제곱수를 걸러낸다. 그 이후 (max - min + 1)에서 체에서 걸러내진 개수를 뺀다.
즉, min ~ max 사이의 개수에서 제곱수의 개수를 빼면 제곱 ㄴㄴ 수의 개수가 된다.

#include <iostream>
#include <cmath>

using namespace std;

bool counted[1000001] = { false };

int main(void) {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    long long min, max;
    cin >> min >> max;

    // 제곱수의 수
    long long count = 0;

    // 2부터 i^2 <= max까지 제곱수의 배수를 카운트
    for (long long i = 2; i * i <= max; i++) {
        // 에라토스테네스의 체에서 min 이상의 값만 검사하면 되므로,
        // i^2 * n를 했을때 min 이상이 되는 첫 n를 구한다.
        long long n = min / (i * i);
        // n이 min 이하일경우 
        if (n * i * i < min) n++;

        // i제곱의 배수를 카운트 (max 이하까지만)
        for (long long j = n; i * i * j <= max; j++) {
            // counted 배열을 위해 (min ~ max)를 0 ~ (max -min) 으로 대응
            long long idx = i * i * j - min;

            // 중복 카운트 방지
            if (!counted[idx]) {
                count++;
                counted[idx] = true;
                //cout << i * i * j << endl;
            }
        }
    }

    int result = (max - min + 1) - count;

    cout << result << "\n";

    return 0;
}