https://www.acmicpc.net/problem/11505
11505번: 구간 곱 구하기
첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이고, K는 구간의 곱을 구하는 횟수이다. 그리고 둘째 줄부터 N+1번째 줄
www.acmicpc.net
[ 문제풀이 ]
이 문제를 풀기 전에 다음 글을 읽고 오시면 좋습니다!!
https://rudalsd.tistory.com/51?category=1073064
[ 자료구조 ] 세그먼트 트리 (Segment Tree)
1. 세그먼트 트리 (Segment Tree) 먼저, 세그먼트 트리가 무엇인지 알아봅시다! 세그먼트 트리는 구간 합을 저장하기 위한 트리입니다. 예를 들어 size가 5인 배열이 있다고 생각해봅시다. int arr [5] = {1
rudalsd.tistory.com
https://rudalsd.tistory.com/45?category=1064608
[ 알고리즘 ] 모듈러 연산(Modular Arithmetic)
오늘은 모듈러 연산에 대해 설명드리겠습니다. 특정 수 M을 넘는 수에 모듈러 연산을 하려면 어떻게 해야 할까요? 모듈러 연산의 특성을 활용하면 쉽게 구할 수 있습니다. [ 동작 원리 ] 정수 A와
rudalsd.tistory.com
정답의 범위가 int의 범위를 벗어나므로 long long 자료형을 써주어야 합니다. 또한, 1,000,000,007로 나눈 나머지 값을 출력해야 하므로 모듈러 연산에 대해서도 알고 있으면 좋습니다.
일반적인 세그먼트 트리와는 다르게 숫자를 0으로 바꾸면 0으로 나누어지는 경우가 생길 수도 있으므로 숫자를 바꿀 때 이 점 유의하셔야 합니다.
[ 소스 코드 ]
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 71 72 73 74 75 76 77 78 79 80 | #include<iostream> #include<vector> #include<cmath> #define ll long long #define MOD 1000000007 using namespace std; int N, M, K; vector<ll> segTree; ll arr[1000001]; ll makeTree(int node, int start, int end) //트리 만들기 { if (start == end) return segTree[node] = arr[start]; int mid = (start + end) / 2; ll left = makeTree(node * 2, start, mid); //왼쪽 자식 노드 ll right = makeTree(node * 2 + 1, mid + 1, end); //오른쪽 자식 노드 return segTree[node] = ((left % MOD) * (right % MOD)) % MOD; } ll gopTree(int node, int start, int end, int sidx, int eidx) //sidx ~ eidx 사이의 곱 { if (end < sidx || start > eidx) return 1; //범위를 벗어나면 if (sidx <= start && eidx >= end) return segTree[node]; //범위에 완전히 포함되면 //범위에 일부 포함되면 int mid = (start + end) / 2; ll left = gopTree(node * 2, start, mid, sidx, eidx); //왼쪽 자식 노드 ll right = gopTree(node * 2 + 1, mid + 1, end, sidx, eidx); //오른쪽 자식 노드 return ((left % MOD) * (right % MOD)) % MOD; } ll changeTree(int node, int start, int end, int idx) { if (idx < start || idx > end) return segTree[node]; //idx가 범위에 포함되지 않으면 if (start == end) { //바꾸고자 하는 노드에 도착하면 return segTree[node] = arr[idx]; } //idx가 범위에 포함되면 int mid = (start + end) / 2; ll left = changeTree(node * 2, start, mid, idx); //왼쪽 자식 노드 ll right = changeTree(node * 2 + 1, mid + 1, end, idx); //오른쪽 자식 노드 return segTree[node] = ((left % MOD) * (right % MOD)) % MOD; } int main() { cin >> N >> M >> K; for (int i = 1; i <= N; i++) { scanf("%lld", &arr[i]); } int size = (1 << (int)(ceil(log2(N)) + 1)); //트리 사이즈 구하기 segTree.resize(size); makeTree(1, 1, N); //트리 만들기 for (int i = 0; i < M + K; i++) { int a, b, c; scanf("%d %d %d", &a, &b, &c); if (a == 1) { //숫자 바꾸기 arr[b] = (ll)c; changeTree(1, 1, N, b); } else { //구간 곱 구하기 ll ans = gopTree(1, 1, N, b, c); ans %= MOD; printf("%lld\n", ans); } } } | cs |
'백준' 카테고리의 다른 글
[ 백준 ] 11689번 - GCD(n, k) = 1 (C++) (0) | 2022.07.11 |
---|---|
[ 백준 ] 3015번 - 오아시스 재결합 (C++) (0) | 2022.07.10 |
[ 백준 ] 2096번 - 내려가기 (C++) (0) | 2022.07.08 |
[ 백준 ] 5639번 - 이진 검색 트리 (C++) (0) | 2022.07.07 |
[ 백준 ] 14502번 - 연구소 (C++) (0) | 2022.07.06 |