-
[백준] 2820 - 자동차 공장Algorithm 문제 2019. 12. 18. 17:45
https://www.acmicpc.net/problem/2820
구간합을 구하는 문제는 아니지만 트리에서 자식들의 갱신이 이루어지는 문제이므로
segment tree와 lazy propagation을 통해 문제를 풀 수 있다.
dfs를 통해 각 사원의 위치를 계산하고 O(lgn) 으로 쿼리를 처리할 수 있다.
<C++ code>
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102#include <cstdio>#include <vector>#include <cmath>using namespace std;int n, m;vector<int> arr, arr_tmp, tree, lazy, l, r;vector<int> child[500001];void pre_order(int i, int &cnt){l[i] = ++cnt;for(int v: child[i]){pre_order(v, cnt);}r[i] = cnt;}void init(int node, int start, int end){if(start == end){tree[node] = arr_tmp[end + 1];return;}init(node * 2, start, (start + end) / 2);init(node * 2 + 1, (start + end) / 2 + 1, end);}void update_lazy(int node, int start ,int end){if(lazy[node] != 0){tree[node] += lazy[node];if(start != end){lazy[node * 2] += lazy[node];lazy[node * 2 + 1] += lazy[node];}lazy[node] = 0;}}void update_range(int node, int start, int end, int left, int right, int diff){update_lazy(node, start, end);if(start > right || left > end) return;if(left <= start && end <= right){tree[node] += diff;if(start != end){lazy[node * 2] += diff;lazy[node * 2 + 1] += diff;}return;}update_range(node * 2, start, (start + end) / 2, left, right, diff);update_range(node * 2 + 1, (start + end) / 2 + 1, end, left, right, diff);}int query(int node, int start, int end, int idx){update_lazy(node, start, end);if(start > idx || end < idx) return 0;if(start == end && start == idx){return tree[node];}return query(node * 2, start, (start + end) / 2, idx) + query(node * 2 + 1, (start + end) / 2 + 1, end, idx);}int main(){scanf("%d %d", &n, &m);arr.resize(n+1);scanf("%d", &arr[1]);for(int i=2; i<=n; i++){int tmp;scanf("%d %d", &arr[i], &tmp);child[tmp].push_back(i);}int cnt = 0;l.resize(n+1);r.resize(n+1);pre_order(1, cnt);int h = (int)ceil(log2(n));int tree_size = (1 << (h+1)) - 1;tree.resize(tree_size);lazy.resize(tree_size);arr_tmp.resize(n+1);for(int i=1; i<=n; i++){arr_tmp[l[i]] = arr[i];}init(1, 0, n-1);while(m--){char q;int a, x;scanf("%*c%c", &q);if(q == 'p'){scanf("%d %d", &a, &x);update_range(1, 0, n-1, l[a], r[a]-1, x);}else{scanf("%d", &a);printf("%d\n", query(1, 0, n-1, l[a] - 1));}}return 0;}cs 'Algorithm 문제' 카테고리의 다른 글
[백준] 14287 - 내리 갈굼 3 (0) 2019.12.19 [백준] 14268 - 내리 갈굼 2 (0) 2019.12.09 [백준] 14267 - 내리갈굼 (0) 2019.12.09 [백준] 17822 - 원판 돌리기 (0) 2019.12.02 [백준] 2357 - 최솟값과 최댓값 (0) 2019.11.30