전형적인 세그먼트 트리 문제인데 함정은 쿼리에 무조건 작은수~큰수라는 조건이 없으므로
조건으로 잘 처리해주면 금방 풀수 있는 문제이다.
바텀업 세그먼트 트리를 구현해서 풀었다.
구간합 구하기 문제는 역시 세그먼트 트리 구현해서 푸는게 짱인거같다...
(내가 아는선에서는... ㅎ)
시간복잡도는 M*NlogN 만큼 소요되는것같다.
주어지는 쿼리의 수가 10만턴정도이니 입출력을 줄여주는것도 시간을 충분히 줄여준다.
참고로 덧셈과정에서 정수형을 넘어갈수 있으니 long long을 사용했다.
<Code>
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 | //pda_pro12 #include<algorithm> #include<iostream> #define N_ 100000 #define INT 0x7fff0000 using namespace std; typedef long long ll; ll a[N_], seg[N_ * 4], n, q; void init(int node, int x, int y) { if (x == y) { seg[node] = a[x]; return; } int mid = (x + y) >> 1; init(node << 1, x, mid); init((node << 1) + 1, mid + 1, y); seg[node] = seg[node << 1] + seg[(node << 1) + 1]; return; } void update(int pos, int val, int node, int x, int y) { if (pos < x || pos > y) return; if (x==y) { seg[node] = val; return; } ll mid = (x + y) >> 1; update(pos, val, node << 1, x, mid); update(pos, val, (node << 1) + 1, mid + 1, y); seg[node] = seg[node << 1] + seg[(node << 1) + 1]; return; } ll query(int lo, int hi, int node, int x, int y) { if (lo > y || hi < x) return 0; if (lo <= x && y <= hi) return seg[node]; ll mid = (x + y) >> 1; ll l = query(lo, hi, node << 1, x, mid); ll r = query(lo, hi, (node << 1) + 1, mid + 1, y); return l+r; } int main() { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> n >> q; for (int i = 1; i <= n; i++) cin >> a[i]; init(1, 1, n); while (q--) { int a, b, c, d; cin >> a >> b >> c >> d; int a1 = (a > b) ? b : a; int b1 = (a > b) ? a : b; cout << query(a1, b1, 1, 1, n) << '\n'; update(c, d, 1, 1, n); } return 0; } |
'PS) BOJ > Segment Tree' 카테고리의 다른 글
[C++] 커피숍2 [백준 1275] (0) | 2018.08.17 |
---|---|
[C++]음주 코딩[백준 5676] (0) | 2018.08.16 |