작심 24/7

[백준] 11659번 구간 합 구하기 4 본문

백준

[백준] 11659번 구간 합 구하기 4

모닝수박 2020. 8. 3. 18:42
 

11659번: 구간 합 구하기 4

첫째 줄에 수의 개수 N (1 ≤ N ≤ 100,000), 합을 구해야 하는 횟수 M (1 ≤ M ≤ 100,000)이 주어진다. 둘째 줄에는 N개의 수가 주어진다. 수는 1,000보다 작거나 같은 자연수이다. 셋째 줄부터 M개의 줄에

www.acmicpc.net

그냥 cin cout 쓰면 무조건 시간 초과 난다.

ios_base::sync_with_stdio(false);
	cin.tie(NULL);

를 적어주거나 scanf printf를 써야 한다.

 

DP와 세그먼트 트리,

두 가지  방식으로 풀어 보았다.

 

1. DP

i번째 칸에 1번째 수부터 i번째 수까지 더한 값을 저장해놓고

a부터 b까지의 합을 출력할 때는

b번째 값에서 a - 1번째 값을 빼서 출력한다.

#include <iostream>
using namespace std;
int N, M, a, b, num;
int arr[100002];
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	cin >> N >> M;
	for (int i = 1; i <= N; i++) {
		cin >> num;
		arr[i] = arr[i - 1] + num;
	}
	for (int i = 0; i < M; i++) {
		cin >> a >> b;
		cout << arr[b] - arr[a - 1] << "\n";
	}
	return 0;
}

 

2. 세그먼트 트리

구간 합 구하기와 같은 방식으로 풀었다.

#include <iostream>
using namespace std;
int N, M, a, b;
int arr[100001], tree[262150];
int Init(int left, int right, int idx) {
	if (left == right) return tree[idx] = arr[left];
	int mid = (left + right) / 2;
	return tree[idx] = Init(left, mid, idx * 2) + Init(mid + 1, right, idx * 2 + 1);
}
int Find(int left, int right, int idx) {
	if (left >= a && right <= b) return tree[idx];
	if (left > b || right < a) return 0;
	int mid = (left + right) / 2;
	return Find(left, mid, idx * 2) + Find(mid + 1, right, idx * 2 + 1);
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	cin >> N >> M;
	for (int i = 0; i < N; i++) cin >> arr[i];
	Init(0, N - 1, 1);
	for (int i = 0; i < M; i++) {
		cin >> a >> b;
		a -= 1, b -= 1;
		cout << Find(0, N - 1, 1) << "\n";
	}
	return 0;
}

'백준' 카테고리의 다른 글

[백준] 17825번 주사위 윷놀이  (0) 2020.08.06
[백준] 17822번 원판 돌리기  (0) 2020.08.04
[백준] 19237번 어른 상어  (0) 2020.08.03
[백준] 17837번 새로운 게임 2  (0) 2020.07.31
[백준] 17779번 게리맨더링 2  (0) 2020.07.29
Comments