반응형
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 81 82 83 84 85 86 87 88 | #include <iostream> #include <cmath> #include <vector> using namespace std; //ary :입력받는 배열 //tree : 새그먼트 트리 //node : 트리의 노드 번호 //start~end까지의 구간의 합 구하기. long long init(vector<long long> &ary, vector<long long> &tree,int node,int start,int end) { if (start == end) return tree[node] = ary[start]; else return tree[node] = init(ary, tree, node * 2, start, (start + end) / 2) + init(ary, tree, node * 2 + 1, (start + end) / 2 + 1, end); } void update_lazy(vector<long long> &tree, vector <long long> &lazy, int node, int start, int end) { if (lazy[node] != 0) { tree[node] += (end - start + 1) * lazy[node]; //leaf node가 아니면 if (start != end) { lazy[node * 2] += lazy[node]; lazy[node * 2 + 1] += lazy[node]; } lazy[node] = 0; } } void update_range(vector<long long> &tree, vector <long long> &lazy, int node, int start, int end, int left, int right, long long diff) { update_lazy(tree, lazy, node, start, end); if (left > end || right < start) return; if (left <= start && right >= end) { tree[node] += (end - start + 1)*diff; if (start != end) { lazy[node * 2] += diff; lazy[node * 2 + 1] += diff; } return; } update_range(tree, lazy, node * 2, start, (start + end) / 2, left, right, diff); update_range(tree, lazy, node * 2 + 1, (start + end) / 2 + 1, end, left, right, diff); tree[node] = tree[node * 2] + tree[node * 2 + 1]; } long long sum(vector <long long>&tree, vector <long long>&lazy, int node, int start, int end, int left, int right) { update_lazy(tree, lazy, node, start, end); if (left>end || right<start) return 0; if (left <= start && right >= end) return tree[node]; return sum(tree, lazy, node * 2, start, (start + end)/2, left, right) + sum(tree, lazy, node * 2 + 1, (start + end) / 2 + 1, end, left, right); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n, m, k, a; cin >> n >> m >> k; vector <long long> ary(n); int h = (int)ceil(log2(n));//트리의 높이는 log2(n) int tree_size = (1 << (h + 1)) - 1; vector <long long> lazy(tree_size); vector <long long> tree(tree_size); for (int i = 0; i < n; i++) cin >> ary[i]; init(ary, tree, 1, 0, n - 1); m += k; while (m--) { int start, end; long long diff; cin >> a; if (a == 1) { cin >> start >> end >> diff; update_range(tree, lazy, 1, 0, n - 1, start-1, end-1, diff); } else if(a == 2) { cin >> start >> end; cout << sum(tree, lazy, 1, 0, n - 1, start - 1, end - 1) <<'\n'; } } } | cs |
'Algorithm' 카테고리의 다른 글
C++(씨쁠쁠)(cplusplus)-백준(baekjoon)(BaekJoon)코딩 10102번:개표 답 (0) | 2017.03.30 |
---|---|
C++(씨쁠쁠)(cplusplus)-백준(baekjoon)(BaekJoon)코딩 10819번:차이를 최대로 답 (0) | 2017.03.27 |
(C++) - 백준(BOJ) 2669 : 직사각형 네개의 합집합의 면적 구하기 답 (0) | 2017.03.27 |
C++(씨쁠쁠)(cplusplus)-백준(baekjoon)(BaekJoon)코딩 2812번:크게 만들기 답 (0) | 2017.03.26 |
C++(씨쁠쁠)(cplusplus)-백준(baekjoon)(BaekJoon)코딩 2812번:크게 만들기(스택) 답 (5) | 2017.03.26 |