문제링크
https://www.acmicpc.net/problem/16978
16978번: 수열과 쿼리 22
길이가 N인 수열 A1, A2, ..., AN이 주어진다. 이때, 다음 쿼리를 수행하는 프로그램을 작성하시오. 1 i v: Ai = v로 변경한다. 2 k i j: k번째 1번 쿼리까지 적용되었을 때, Ai, Ai+1, ..., Aj의 합을 출력한다.
www.acmicpc.net
풀이
- 구간합 쿼리의 처리 순서를 적용된 업데이트 쿼리 개수에 대해 오름차순으로 처리한다.
- 각 구간합 쿼리에 대해 지금까지 적용된 업데이트 쿼리개수 보다 적용해야될 업데이트쿼리 개수가 많으면 진행시켜서 구간합을 구한다.
코드
- 시간복잡도: O(MlogM+MlogN)
#include <bits/stdc++.h> using namespace std; #define all(v) (v).begin(), (v).end() #define rall(v) (v).rbegin(), (v).rend() int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int N; cin >> N; vector<long long> a(N), t(2 * N, 0); for (int i = 0; i < N; ++i) { cin >> a[i]; t[N + i] = a[i]; } for (int i = N - 1; i >= 1; --i) { t[i] = t[i << 1] + t[i << 1 | 1]; } auto sum = [&](int l, int r) { long long ret = 0; for (l += N, r += N; l < r; l >>= 1, r >>= 1) { if (l & 1) ret += t[l++]; if (r & 1) ret += t[--r]; } return ret; }; auto update = [&](int p, long long val) { for (t[p += N] = val; p > 1; p >>= 1) { t[p >> 1] = t[p] + t[p ^ 1]; } }; int M; cin >> M; vector<pair<int, long long> > q1; map<int, vector<tuple<int, int, int> > > q2; for (int i = 0; i < M; ++i) { long long a, b, c, d; cin >> a; if (a == 1) { cin >> b >> c; --b; q1.push_back({b, c}); } else { cin >> b >> c >> d; --c; --d; q2[b].push_back({i, c, d}); } } int done = -1; vector<pair<int, long long> > answer; for (auto it = q2.begin(); it != q2.end(); ++it) { for (int i = done + 1; i < it -> first; ++i) { update(q1[i].first, q1[i].second); } done = it -> first - 1; for (auto [i, l, r]: it -> second) { answer.push_back({i, sum(l, r + 1)}); } } sort(all(answer)); for (auto e: answer) { cout << e.second << '\n'; } }
728x90
'PS > BOJ' 카테고리의 다른 글
백준 13263번: 나무 자르기 (0) | 2022.03.06 |
---|---|
백준 4008번: 특공대 (0) | 2022.03.06 |
백준 13548번: 수열과 쿼리 6 (0) | 2022.02.28 |
백준 1420번: 학교 가지마! (0) | 2022.02.26 |
백준 10254번: 고속도로 (0) | 2022.02.26 |