문제
- 문제 링크
BOJ 25462 - Inverzije
길이 $N$인 수열과 $Q$개의 구간 쿼리가 주어진다.
각 쿼리에 맞는 답을 출력하자.
TL : $4$ sec, ML : $1024$ MB
$1 ≤ N, Q ≤ 100,000$ $1 ≤ a_i, b_i, P_i ≤ N$
알고리즘 분류
- 자료 구조(data structures)
- 세그먼트 트리(segment tree)
- 오프라인 쿼리(offline_queries)
- mo's(mo's algorithm)
풀이
수쿼 $23$ 을 풀어 봤다면 보자마자 솔루션이 떠올랐을 것이다.
쿼리 내용 보자.
전형적인 $mo's$ 문제 형태이다.
어떤 수 $x$가 현재 보고 있는 구간의 끝점에서 추가될 때 / 제거될 때 로 나눠 생각해보자.
작은 수 / 큰 수 가 갈리는 이유는 당연히 구간의 끝 점이 왼 쪽에서 변하냐, 오른 쪽에서 변하냐에 따라 취급 기준이 달라지기 때문이다.
또한 구간 관리는 세그먼트 트리를 이용하면 간단하고 효율적으로 관리할 수 있다.
하나 유의할 건 재귀 세그보다 펜윅 세그를 이용하도록 하자.
이렇게 자잘한 업데이트가 많이 일어나는 상황에선 재귀 / 펜윅 간에 상수 차이를 무시할 수 없다.
최종적으로 약 $O(max(N, Q) * √NlogN)$ 정도로 문제를 해결할 수 있다.
전체 코드
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 | #include<bits/stdc++.h> #define N 100001 using namespace std; struct _Q { int s, e, i; }Q[N]; long long t, an[N]; int n, q, seg[N], c[N]; void Init() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> q; for (int i(1); i <= n; cin >> c[i++]); for (int i{}; i < q; i++) cin >> Q[i].s >> Q[i].e, Q[i].i = i; } void f(int p, int q) { while (p <= N - 1) seg[p] += q, p += p & -p; } int g(int p, int r = 0) { while (p) r += seg[p], p -= p & -p; return r; } void Solve(int s, int e) { sort(Q, Q + q, [](_Q x, _Q y) { x.s /= 400, y.s /= 400; return x.s ^ y.s ? x.s < y.s : x.e < y.e; }); for (int i{}; i < q; i++) { while (s > Q[i].s) t += g(c[--s] - 1), f(c[s], 1); while (s < Q[i].s) t -= g(c[s] - 1), f(c[s++], -1); while (e > Q[i].e) t -= g(N - 1) - g(c[e]), f(c[e--], -1); while (e < Q[i].e) t += g(N - 1) - g(c[++e]), f(c[e], 1); an[Q[i].i] = t; } for (int i{}; i < q; cout << an[i++] << '\n'); } int main() { Init(); Solve(Q[0].s, Q[0].s - 1); } | cs |
comment
끝
'Problem Solving > Baekjoon Online Judge (Platinum)' 카테고리의 다른 글
백준 23840 - 두 단계 최단 경로 4 (C++) (0) | 2023.05.09 |
---|---|
백준 26262 - 트리 더하기 1 (C++) (0) | 2023.05.07 |
백준 11412 - Tree of Almost Clean Money (C++) (0) | 2023.05.04 |
백준 26615 - 다오의 행사 계획하기 (C++) (0) | 2023.05.03 |
백준 16453 - Linhas de Metrô (C++) (0) | 2023.05.01 |