티스토리 뷰
문제
알고리즘
세그먼트트리
풀이
부대원의 숫자가 계속해서 바뀔 때, 몇번째 병사가 어디 부대에 들어있는지 묻는 문제입니다.
누적배열을 만들어 나이브하게 해결해봅시다. 부대원이 변경될때마다 누적배열을 변경하는데에 최대 $O(N)$의 복잡도를 요구하게됩니다. 업데이트를 더 빠르게 할 수 있는 세그먼트 트리를 요구합니다.
세그먼트 트리를 사용하면 업데이트와 쿼리가 $O(logN)$에 해결가능합니다. 남은 문제는 누적배열에서 몇번째에 해당하는$K$가 어디에 속한지 찾는 문제입니다. 누적배열은 오름차순의 형태를 띠고 있고 이는 이분탐색을 통해 접근할 수 있다는 의미입니다.
펜윅트리에서 쿼리는 누적합을 리턴하므로 펜윅트리 + 이분탐색을 통해 문제를 해결할 수 있습니다.
코드
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;++i)
#define REP(i,n) for(int i=1;i<=n;++i)
#define FAST cin.tie(NULL);cout.tie(NULL); ios::sync_with_stdio(false)
using namespace std;
const int MAXS = 500'000;
int N,x,Q,a,b,c;
int fenwick[MAXS + 1];
void update(int idx, int val) {
while (idx <= N) {
fenwick[idx] += val;
idx += idx & -idx;
}
}
int query(int idx) {
int ret = 0;
while (idx) {
ret += fenwick[idx];
idx -= idx & -idx;
}
return ret;
}
int main() {
FAST;
cin >> N;
REP(i, N) {
cin >> x;
update(i, x);
}
cin >> Q;
while (Q--) {
cin >> a;
if (a == 1) {
cin >> b >> c;
update(b, c);
}
else {
cin >> b;
int lo = 1;
int hi = N;
int best;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (query(mid) >= b) {
best = mid;
hi = mid - 1;
}
else lo = mid + 1;
}
cout << best << '\n';
}
}
return 0;
}
'Algorithm' 카테고리의 다른 글
[백준 1507] 궁금한 민호 (0) | 2020.09.14 |
---|---|
[백준 2517] 달리기 (0) | 2020.09.12 |
[백준 2720] 세탁소 사장 동혁 (0) | 2020.09.08 |
[백준 10999] 구간 합 구하기2 (0) | 2020.09.07 |
[백준 5419] 북서풍 (0) | 2020.09.06 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- union find
- knapsack
- Oracle
- 펜윅트리
- 좌표압축
- dijkstra
- 2-SAT
- string
- Fenwick
- DP
- bfs
- SCC
- greedy
- kmp
- 이분탐색
- Segment tree
- 동적계획법
- 세그먼트트리
- 트라이
- dfs
- Suffix Array
- 이분매칭
- spring boot
- sorting
- sweeping
- hld
- 스위핑
- 정렬
- implementation
- spring
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함