BOJ_1407_2로 몇 번 나누어질까
BOJ_1407_2로 몇 번 나누어질까
[Gold IV] 2로 몇 번 나누어질까 - 1407
성능 요약
메모리: 14312 KB, 시간: 100 ms
분류
수학
제출 일자
2024년 10월 22일 05:09:50
문제 설명
자연수 N이 주어지면, 자연수를 유지하면서 N을 2로 몇 번까지 나눌 수 있는지를 생각해 볼 수 있다. 즉, N의 모든 약수 중 2의 거듭제곱 꼴이면서 가장 큰 약수를 생각하는 것이다. 예를 들어 15의 경우는 2로 한 번도 나눌 수 없으므로 2^0 = 1이 해당되고, 40의 경우는 2로 세 번까지 나눌 수 있으므로 2^3 = 8이 해당된다. 이러한 약수를 함수값으로 가지는 함수 f(x)를 정의하자. 즉, f(15) = 1이고, f(40) = 8이다.
두 자연수 A, B(A≤B)가 주어지면, A 이상 B 이하의 모든 자연수에 대해서, 그 자연수의 모든 약수 중 2의 거듭제곱 꼴이면서 가장 큰 약수들의 총 합을 구하는 프로그램을 작성하시오. 즉 아래와 같은 수식의 값을 구해야 한다.
f(A) + f(A+1) + ... + f(B-1) + f(B)
입력
첫째 줄에 자연수 A와 B가 빈 칸을 사이에 두고 주어진다. (1≤A≤B≤10^15)
출력
첫째 줄에 구하고자 하는 수를 출력한다.
문제 풀이
1의배수 - 2의배수 - 4의배수 이런식으로 좁혀 찾아나가고 이렇게 새로 찾으면 /2를 더해주면 된다. 4를 찾으면 2를 더했으므로 나머지 2 더해주기 이런식.
코드
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
32
33
34
/**
* Author: nowalex322, Kim HyeonJae
*/
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br;
static BufferedWriter bw;
static StringTokenizer st;
static long A, B;
public static void main(String[] args) throws Exception {
new Main().solution();
}
public void solution() throws Exception {
br = new BufferedReader(new InputStreamReader(System.in));
// br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));
bw = new BufferedWriter(new OutputStreamWriter(System.out));
st = new StringTokenizer(br.readLine());
A = Long.parseLong(st.nextToken());
B = Long.parseLong(st.nextToken());
long res = calNum(B) - calNum(A-1);
bw.write(String.valueOf(res));
bw.flush();
bw.close();
br.close();
}
private long calNum(long num) {
long tmp = num;
for(long i=2; i<=num; i<<=1) {
tmp += (num/i) * (i>>1);
}
return tmp;
}
}
This post is licensed under
CC BY 4.0
by the author.