[백준 Java] 1407번 2로 몇 번 나누어질까(정수론)

2024. 1. 4. 01:29·Algorithm/PS - 백준
728x90
반응형

💡문제

[Gold IV] 2로 몇 번 나누어질까 - 1407

문제 링크

성능 요약

메모리: 11552 KB, 시간: 76 ms


🌟풀이

범위가 무려 1≤A≤B≤$10^{15}$ 로 엄청나다.
그래서 A ~ B 까지 순회하면서 더할 수는 없다.

1 ~ n까지 소수 x의 배수의 개수를 구하는 방식을 이용하였다.

1 ~ n까지 수들은 소수 x로 몇번 나누어 떨어질까 ?

1부터 20까지 순회하며 각 수를 소인수분해 했을때 2가 몇 번씩 들어가는지 적어보았다.

이를 2가 들어간 횟수만큼 동그라미로 표현하게 되면 아래 사진과 같이 표시되며 오른쪽과 같은 의미를 가질 수 있다.

위를 참고하여

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |

2로 나누어 지지 않는 수(홀수)는 $2^0 = 1$인 2의 거듭제곱 꼴 중 가장 큰 약수를 가진다.

그러면 여기서 홀수의 개수는 어떻게 구할까 ?
-> ceil(20/2) = 10


| 2 | 4 | 6 | 8 | 10 | 12 | 14 | 16 | 18 | 20 |

4로 나누어 지지 않는 수는 $2^1 = 2$인 2의 거듭제곱 꼴 중 가장 큰 약수를 가진다.
그러면 여기서 4로 나누어 지지 않는 수의 개수는 어떻게 구할까 ?
-> ceil(10/2) = 5


| 4 | 8 | 12 | 16 | 20 |

8로 나누어 지지 않는 수는 $2^2 = 4$인 2의 거듭제곱 꼴 중 가장 큰 약수를 가진다.
그러면 여기서 8로 나누어 지지 않는 수의 개수는 어떻게 구할까 ?
-> ceil(5/2) = 3 (이런 경우 때문에 올림을 해야한다)


| 8 | 16 |

16로 나누어 지지 않는 수는 $2^3 = 8$인 2의 거듭제곱 꼴 중 가장 큰 약수를 가진다.
그러면 여기서 8로 나누어 지지 않는 수의 개수는 어떻게 구할까 ?
-> ceil(2/2) = 1


| 16 |

32로 나누어 지지 않는 수는 $2^4 = 16$인 2의 거듭제곱 꼴 중 가장 큰 약수를 가진다.
그러면 여기서 16로 나누어 지지 않는 수의 개수는 어떻게 구할까 ?
-> ceil(1/2) = 1




이렇게 $2^0$ ~ $2^4$ 들을 가장 큰 약수로 가지는 수들의 개수를 각각 알아봤다.
이 수를 다 더하면

1*10 + 2*5 + 4*3 + 8*1 + 16*1 = 56
이며 이 숫자는 1 ~ 20까지의 2의 거듭제곱큰약수들의 합이 된다.

이를 이용하여 1 ~ B 에서 1 ~ A-1을 빼주면 A~B까지의 합을 구할 수 있다.
f(B) - f(A-1)




👩‍💻 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main_1407 {
    static long A;
    static long B;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        A = Long.parseLong(st.nextToken());
        B = Long.parseLong(st.nextToken());

        // A부터 B까지의 수 중 2의 거듭제곱 꼴이면서 가장 큰 약수를 찾아 더하여 출력
        System.out.println(twoCount(B) - twoCount(A - 1));
    }

    /**
     * A부터 B까지의 수 중 2의 거듭제곱 꼴이면서 가장 큰 약수를 찾아 더하는 메서드
     *
     * @param n 약수를 찾을 대상 숫자
     * @return 2의 거듭제곱 꼴이면서 가장 큰 약수를 찾아 더한 결과
     */
    private static long twoCount(long n) {
        long result = 0;
        long divisor = 1;

        // 2의 거듭제곱 꼴이면서 가장 큰 약수를 찾기 위한 반복문
        while (n > 0) {
            // 현재의 divisor로 나누어지지 않는 숫자의 가장 큰 약수를 찾아 더함
            long indivisibleNumberCnt = n / divisor;

            // 결과에 현재 divisor와 가장 큰 약수를 곱하여 누적
            result += divisor * indivisibleNumberCnt;

            // 다음 거듭제곱으로 이동
            divisor *= 2;
        }
        return result;
    }
}
[[ 참고 ] (https://velog.io/@bgg01578/%EB%B0%B1%EC%A4%80-1407-2%EB%A1%9C-%EB%AA%87-%EB%B2%88-%EB%82%98%EB%88%84%EC%96%B4%EC%A7%88%EA%B9%8C)]
반응형

'Algorithm > PS - 백준' 카테고리의 다른 글

[백준 Java] 23888번 등차수열과 쿼리 (정수론)  (1) 2024.01.08
[백준 Java] 6219번 소수의 자격 (정수론)  (1) 2024.01.07
[백준 Java] 17071번 숨바꼭질5 (BFS)  (0) 2023.08.10
[백준 Java] 9328번 열쇠 (구현, BFS)  (1) 2023.08.09
[백준 Java] 2252번 줄 세우기 ( 그래프 , 위상정렬)  (0) 2023.06.26
'Algorithm/PS - 백준' 카테고리의 다른 글
  • [백준 Java] 23888번 등차수열과 쿼리 (정수론)
  • [백준 Java] 6219번 소수의 자격 (정수론)
  • [백준 Java] 17071번 숨바꼭질5 (BFS)
  • [백준 Java] 9328번 열쇠 (구현, BFS)
제가안난데여♪(´ε`*)
제가안난데여♪(´ε`*)
기억의 유한함을 기록의 무한함으로 ✍️ 예비 개발자가 꿈꾸는 공간 여기는 안나의 개발 블로그 💻
  • 제가안난데여♪(´ε`*)
    안나의 전두엽 어딘가 🧠
    제가안난데여♪(´ε`*)
    기억의 유한함을 기록의 무한함으로 ✍️ 예비 개발자가 꿈꾸는 공간 여기는 안나의 개발 블로그 💻
  • 전체
    오늘
    어제
    • 분류 전체보기 (128)
      • 간단하게 한스푼🥄 (1)
      • Programming (56)
        • Spring (16)
        • Vue.js (6)
        • Deep Learning (3)
        • DataBase (5)
        • React (26)
      • DevOps (21)
        • Docker (12)
        • Linux (4)
      • Algorithm (46)
        • 알고리즘 정리 (5)
        • 자료구조 (0)
        • PS - 백준 (28)
        • 99클럽 코테 스터디 (13)
      • Project (0)
        • CampFire (0)
      • 안나의 취뽀일기 (˵ •̀ ᴗ - ˵ ) ✧ (4)
        • SSAFY_9기 (2)
        • SW 부트캠프 (2)
  • 잔디 달력

    «   2025/07   »
    일 월 화 수 목 금 토
    1 2 3 4 5
    6 7 8 9 10 11 12
    13 14 15 16 17 18 19
    20 21 22 23 24 25 26
    27 28 29 30 31
  • 인기 글

  • 태그

    백준 구현문제
    Spring
    React
    springboot
    리액트 상태
    greedy
    Vue
    linux
    백준
    항해99
    99클럽
    til
    도커컨테이너
    Vue.js
    김영한
    java
    Vue.js 입문하기
    front-end
    java 백준
    알고리즘
    자바
    topology sort
    개발자 취업
    java stack
    stack
    도커
    코딩테스트 준비
    자바 스택
    백준 java
    docker
  • 07-12 00:34
    반응형
  • hELLO· Designed By정상우.v4.10.3
제가안난데여♪(´ε`*)
[백준 Java] 1407번 2로 몇 번 나누어질까(정수론)
상단으로

티스토리툴바