백준16975 수열과 쿼리21 작성일 2019-02-23 | In PS 문제 링크 http://icpc.me/16975 사용 알고리즘 Segment Tree Lazy Propagation 시간복잡도 O(M log N) 풀이 Lazy Propagation을 구현해주면 됩니다. 약 1011까지 수가 커질 수 있으니 주의하시면 됩니다. 전체 코드 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788#include <bits/stdc++.h> using namespace std; template <typename T> class segmentTree{ private: vector<T> tree; vector<T> lazy; int n, h, size; T _init(int node, int start, int end){ if(start == end) return tree[node] = arr[start]; int mid = (start+end)>>1; return tree[node] = _init(node*2, start, mid) + _init(node*2+1, mid+1, end); } void update_lazy(int node, int start, int end, int left, int right){ if(!lazy[node]) 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; } void update_range(int node, int start, int end, int left, int right, T diff){ update_lazy(node, start, end, left, right); if(right<start || end<left) return; if(left<=start && end<=right){ tree[node] += (end-start+1)*diff; if(start^end){ lazy[node*2] += diff; lazy[node*2+1] += diff; } return; } int mid = (start+end)>>1; update_range(node*2, start, mid, left, right, diff); update_range(node*2+1, mid+1, end, left, right, diff); tree[node] = tree[node*2] + tree[node*2+1]; } T q(int node, int start, int end, int left, int right){ update_lazy(node, start, end, left, right); if(right<start || end<left) return 0; if(left<=start && end<=right) return tree[node]; int mid = (start+end)>>1; return q(node*2, start, mid, left, right) + q(node*2+1, mid+1, end, left, right); } public: vector<T> arr; void init(){ _init(1, 0, n-1); } segmentTree(){ this->n = 0; this->h = 0; this->size = 0; } segmentTree(int n){ this->n = n; h = (int)ceil(log2(n))+1; size = 1<<h; arr = vector<T>(n); tree = vector<T>(size); lazy = vector<T>(size); } void update(int left, int right, T diff){ update_range(1, 0, n-1, left-1, right-1, diff); } T query(int left, int right){ return q(1, 0, n-1, left-1, right-1); } }; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); int n, m, k; cin >> n; segmentTree<long long> st(n); for(int i=0; i<n; i++) cin >> st.arr[i]; st.init(); cin >> m; while(m--){ int a, b, c; long long d; cin >> a >> b; if(a == 1){ cin >> c; cin >> d; st.update(b, c, d); }else{ cout << st.query(b, b) << "\n"; } } }