알고리즘/백준
[백준] 16975번 - 수열과 쿼리 21
래울
2024. 8. 28. 23:22
가끔 풀다보면 간간히 보이는 Lazy Segment 문제
세그먼트 트리에서 특정 구간에 대해 업데이트를 Lazy하게 해준다. 나중에 시간나면 따로 정리하면 좋을 듯
문제
https://www.acmicpc.net/problem/16975
코드
#include <iostream>
#include <queue>
#include <vector>
#include <cmath>
#include <stack>
#include <algorithm>
#include <map>
#include <unordered_map>
using namespace std;
int N, M;
long long arr[100000];
vector<long long> tree;
vector<long long> lazy;
long long Make(int node, int start, int end)
{
if (start == end) {
tree[node] = arr[start];
return tree[node];
}
int mid = (start + end) / 2;
long long l = Make(node * 2, start, mid);
long long r = Make(node * 2 + 1, mid + 1, end);
tree[node] = l + r;
return tree[node];
}
void Lazy_Update(int node, int start, int end)
{
if (lazy[node] != 0)
{
tree[node] = tree[node] + (end - start + 1) * lazy[node];
if (start != end)
{
lazy[node * 2] += lazy[node];
lazy[node * 2 + 1] += lazy[node];
}
lazy[node] = 0;
}
}
long long Query(int node, int start, int end, int left, int right)
{
Lazy_Update(node, start, end);
if (start > right || end < left) return 0;
if (left <= start && end <= right) {
return tree[node];
}
int mid = (start + end) / 2;
long long l = Query(node * 2, start, mid, left, right);
long long r = Query(node * 2 + 1, mid + 1, end, left, right);
return l + r;
}
void Update(int node, int start, int end, int left, int right, long long value)
{
Lazy_Update(node, start, end);
if (right < start || left > end) return;
if (left <= start && end <= right)
{
tree[node] = tree[node] + (end - start + 1) * value;
if (start != end)
{
lazy[node * 2] += value;
lazy[node * 2 + 1] += value;
}
return;
}
int mid = (start + end) / 2;
Update(node * 2, start, mid, left, right, value);
Update(node * 2 + 1, mid + 1, end, left, right, value);
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}
int main()
{
// 노드가 전부 연결, 차수가 홀수인 노드가 0 or 2 개
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> N;
for (int i = 0; i < N; ++i) cin >> arr[i];
int height = ceil(log2(N)) + 1;
tree.resize(1 << height);
lazy.resize(1 << height);
Make(1, 0, N - 1);
cin >> M;
for (int i = 0; i < M; ++i)
{
int p;
cin >> p;
if (p == 1) {
//query
int a, b, c;
cin >> a >> b >> c;
Update(1, 0, N - 1, a - 1, b - 1, c);
}
else {
//update
int a;
cin >> a;
cout << Query(1, 0, N - 1, a - 1, a - 1) << "\n";
}
}
return 0;
}