문제 링크
풀이
세그먼트 트리를 이용하여 풀이 할 수 있다.
i > j이면서 arr[i] < arr[j]인 쌍의 개수를 구하면 된다.
arr[i]를 작은 것부터 세그먼트 트리에 1로 업데이트 시켜주면 arr[i] < arr[j] 조건은 알아서 맞춰지게 되고 i > j를 만족하는 것의 개수만 카운트 하면 된다.
코드
#include <iostream>
#include <algorithm>
using namespace std;
using ll = long long;
pair<ll, ll> arr[500005];
ll tree[2000006], ans;
ll query(int cur, int s, int e, int qs, int qe) {
if (e < qs || qe < s) return 0;
if (qs <= s && e <= qe) return tree[cur];
ll mid = (s + e) >> 1;
ll left = query(2 * cur, s, mid, qs, qe);
ll right = query(2 * cur + 1, mid + 1, e, qs, qe);
return left + right;
}
void update(int cur, int s, int e, int idx) {
if (s == e) { tree[cur] = 1; return; }
int mid = (s + e) >> 1;
if (idx <= mid) update(2 * cur, s, mid, idx);
else update(2 * cur + 1, mid + 1, e, idx);
tree[cur] = tree[2 * cur] + tree[2 * cur + 1];
}
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
int n; cin >> n;
for (int i = 0; i < n; i++) {
int ipt; cin >> ipt;
arr[i] = {ipt, i};
}
sort(arr, arr + n);
for (int i = 0; i < n; i++) {
int idx = arr[i].second;
ans += query(1, 0, n - 1, idx + 1, n - 1);
update(1, 0, n - 1, idx);
}
cout << ans;
}
'Algorithm > BOJ' 카테고리의 다른 글
백준[16975] 수열과 쿼리 21 (0) | 2021.08.16 |
---|---|
백준[9345] 디지털 비디오 디스크(DVDs) (0) | 2021.08.15 |
백준[11660] 구간 합 구하기 5 (0) | 2021.08.10 |
백준[16991] 외판원 순회 3 (0) | 2021.08.10 |
백준[3648] 아이돌 (0) | 2021.08.06 |