🔺 문제
11505번: 구간 곱 구하기
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 곱을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄
www.acmicpc.net
🔺 코드
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
import java.util.*;
import java.io.*;
public class Main {
static int MOD = 1000000007;
public static long[] arr, tree;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()," ");
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int K = Integer.parseInt(st.nextToken());
arr = new long[N + 1];
for(int i = 1 ; i <= N ; i++) {
arr[i] = Long.parseLong(br.readLine());
}
// 트리 초기화
tree = new long[N * 4];
init(1, N, 1);
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < M + K ; i++) {
st = new StringTokenizer(br.readLine()," ");
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
long c = Long.parseLong(st.nextToken());
if(a == 1) {
arr[b] = c;
update(1, N, 1, b, c);
}
else if(a == 2) {
sb.append(multiple(1, N, 1, b, (int) c) + "\n");
}
}
System.out.println(sb);
br.close();
}
// 각 구간별 구간 곱 저장
public static long init(int start, int end, int node) {
if(start == end) return tree[node] = arr[start];
int mid = (start + end) / 2;
return tree[node] = (init(start, mid, node * 2) * init(mid + 1, end, node * 2 + 1)) % MOD;
}
// left ~ right 범위 내의 구간 곱 찾음
public static long multiple(int start, int end, int node, int left, int right) {
if(right < start || end < left) return 1; // 범위 밖에 있는 경우
if(left <= start && end <= right) return tree[node]; // 범위 안에 있는 경우
int mid = (start + end) / 2;
return (multiple(start, mid, node * 2, left, right) * multiple(mid + 1, end, node * 2 + 1, left, right)) % MOD;
}
// 수정 메소드 (idx : 구간 곱 수정하고자 하는 노드 / val : 수정할 값)
public static long update(int start, int end, int node, int idx, long val) {
if(idx < start || end < idx) return tree[node]; // 범위 밖에 있으면 tree 값 수정하지 않고 바로 리턴
if(start == end) return tree[node] = val; // 범위 안에 있으면 리프 노드 업데이트
int mid = (start + end) / 2;
return tree[node] = (update(start, mid, node * 2, idx, val) * update(mid + 1, end,node * 2 + 1, idx, val)) % MOD;
}
}
|
cs |
✅ 해결 아이디어
✔ 세그먼트 트리 : 구간 곱 구하기
- MOD 연산
💥 유의사항
⇨ 세그먼트 트리 초기화 시, 숫자가 범위 밖에 있는 경우, 초깃값을 1로 지정 (55번째 줄)
⇨ 연결된 가지 부분 전체 갱신 (리프 노드 → 루프 노드)
🔺 다른 풀이들
- 왜 long형으로 해야하는지 이유 & 모듈러 연산 설명
백준 11505번 구간 곱 구하기 (JAVA)
백준 11505번 구간 곱 구하기 https://www.acmicpc.net/problem/11505 11505번: 구간 곱 구하기 첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나
lucysworld.tistory.com
- 자세한 설명 굿! (복습용)
[JAVA/백준] 11505번: 구간 곱 구하기
PS & 개발 기록
iamheesoo.github.io
💬 느낀 점
세그먼트 트리..
이제야 좀 알 것 같아 널~~
1회독 | 2회독 | 3회독 | 4회독 | 5회독 |
V |
(참고)
[BOJ] 백준 2042번 : 구간 합 구하기 (JAVA)
문제 어떤 N개의 수가 주어져 있다. 그런데 중간에 수의 변경이 빈번히 일어나고 그 중간에 어떤 부분의 합을 구하려 한다. 만약에 1,2,3,4,5 라는 수가 있고, 3번째 수를 6으로 바꾸고 2번째부터 5번
steady-coding.tistory.com
'코테 > 백준' 카테고리의 다른 글
[백준/JAVA] 11438번: LCA 2 (0) | 2023.05.10 |
---|---|
[백준/JAVA] 11437번: LCA (0) | 2023.05.10 |
[백준/JAVA] 10868번: 최솟값 (0) | 2023.05.09 |
[백준/JAVA] 2042번: 구간 합 구하기 (0) | 2023.05.09 |
[백준/JAVA] 1068번: 트리 (0) | 2023.05.07 |