티스토리 뷰

반응형

✏️ 문제 링크

https://www.acmicpc.net/problem/16975

 

16975번: 수열과 쿼리 21

길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i j k: Ai, Ai+1, ..., Aj에 k를 더한다. 2 x: Ax 를 출력한다.

www.acmicpc.net

 

✏️ 문제 설명

 

 

✏️ 문제 풀이

이 문제 역시 느리게 갱신되는 세그먼트 트리로 구현하는 문제입니다.

여기서 조금 더 생각해 봐야 할 것은 x번째 원소를 출력하는 건데, x번째 인덱스를 구하는 과정은

이분 탐색 과정을 통해서 값을 찾아낼 수 있습니다.

아래 문제는 느리게 갱신되는 세그먼트 트리의 기본 틀을 구현한 문제입니다.

https://pooreumjung.tistory.com/334

 

[C/C++] 백준 10999번 - 구간 합 구하기 2

✏️ 문제 링크 https://www.acmicpc.net/problem/10999 10999번: 구간 합 구하기 2 첫째 줄에 수의 개수 N(1 ≤ N ≤ 1,000,000)과 M(1 ≤ M ≤ 10,000), K(1 ≤ K ≤ 10,000) 가 주어진다. M은 수의 변경이 일어나는 횟수이

pooreumjung.tistory.com

 

 

✏️ 문제 코드

#include<iostream>
#include<vector>
using namespace std;

#define ll long long
vector<ll>arr, tree, lazy;
ll initTree(ll node, ll start, ll end);
ll update(ll node, ll start, ll end, ll l, ll r, ll diff);
void lazyUpdate(ll node, ll start, ll end);
ll findValue(ll node, ll start, ll end, ll index);
int main() {

	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int N, M;
	cin >> N;

	arr.resize(N + 1);
	tree.resize(N * 4);
	for (int i = 1; i <= N; i++)
		cin >> arr[i];

	initTree(1, 1, N);
	lazy.resize(N * 4);

	cin >> M;
	int query;
	while (M--) {
		cin >> query;
		if (query == 1) {
			ll l, r, value;
			cin >> l >> r >> value;
			update(1, 1, N, l, r, value);
		}
		else if (query == 2) {
			ll index;
			cin >> index;
			cout << findValue(1, 1, N, index) << '\n';
		}
	}
}

ll initTree(ll node, ll start, ll end)
{
	if (start == end)
		return tree[node] = arr[start];

	ll mid = (start + end) / 2;

	ll leftSum = initTree(node * 2, start, mid);
	ll rightSum = initTree(node * 2 + 1, mid + 1, end);

	return tree[node] = leftSum + rightSum;
}

ll update(ll node, ll start, ll end, ll l, ll r, ll diff)
{
	lazyUpdate(node, start, end);

	if (r < start || end < l)
		return tree[node];

	if (l <= start && end <= r) {
		lazy[node] += diff;
		lazyUpdate(node, start, end);
		return tree[node];
	}

	ll mid = (start + end) / 2;
	ll leftSum = update(node * 2, start, mid, l, r, diff);
	ll rightSum = update(node * 2 + 1, mid + 1, end, l, r, diff);

	return tree[node] = leftSum + rightSum;
}

void lazyUpdate(ll node, ll start, ll end)
{
	if (lazy[node] == 0)
		return;

	tree[node] += (end - start + 1) * lazy[node];

	if (start != end) {
		lazy[node * 2] += lazy[node];
		lazy[node * 2 + 1] += lazy[node];
	}

	lazy[node] = 0;
}

ll findValue(ll node, ll start, ll end, ll index)
{
	lazyUpdate(node, start, end);

	if (start == end)
		return tree[node];

	ll mid = (start + end) / 2;
	if (index <= mid)
		return findValue(node * 2, start, mid, index);
	else
		return  findValue(node * 2 + 1, mid + 1, end, index);
}

 

 

 

✏️ 수열과 쿼리 문제 더 보기

https://pooreumjung.tistory.com/328

 

[C/C++] 백준 18436번 - 수열과 쿼리 37

✏️ 문제 링크 https://www.acmicpc.net/problem/18436 18436번: 수열과 쿼리 37 길이가 N인 수열 A1, A2, ..., AN이 있다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i x: Ai를 x로 바꾼다. 2 l r: l ≤ i ≤

pooreumjung.tistory.com

https://pooreumjung.tistory.com/313

 

[C/C++] 백준 - 수열과 쿼리 문제

✏️ 문제 링크 https://www.acmicpc.net/problem/14438 14438번: 수열과 쿼리 17 길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i v : Ai를 v로 바꾼다. (1 ≤ i

pooreumjung.tistory.com

 

✏️ 세그먼트 트리 문제 더 보기

https://pooreumjung.tistory.com/330

 

[C/C++] 백준 5676번 - 음주 코딩

✏️ 문제 링크 https://www.acmicpc.net/problem/5676 5676번: 음주 코딩 각 테스트 케이스마다 곱셈 명령의 결과를 한 줄에 모두 출력하면 된다. 출력하는 i번째 문자는 i번째 곱셈 명령의 결과이다. 양수인

pooreumjung.tistory.com

https://pooreumjung.tistory.com/314

 

[C/C++] 백준 - 머지 소트 트리 문제

머지 소트 트리(Merge Sort Tree)는 트리의 일종으로 merge sort과정을 그대로 트리 모양으로 접합시킨 트리 트리의 높이는 log N 정도이고, 하나의 층에 총 N개의 원소가 있으므로 공간복잡도 역시 O(N log

pooreumjung.tistory.com

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/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
글 보관함