[트리] [시도x] MEASURETIME
2021. 2. 8. 19:44ㆍ알고리즘/알고리즘 문제 [hard]
1. 펜윅트리를 이용한 풀이
처음에 이 문제를 봤을때
펜윅트리를 어떻게 써야할 지 감을 못잡았다.
책에서는 수열의 입력값으로 이루어진 트리를 만들고
해당 입력값이 오게되면 그것을 포함하는 구간을 전부 +1을 해줘서
루트에 현재 수열의 길이를 저장하게 되고
입력값 까지의 부분합을 구하게 되면
현재 수열중에서 입력값보다 작은 것들의 개수를 알 수 있다.
이를 통해 자신보다 큰 원소의 개수를 알 수 있고, 앞으로 몇칸 이동 시켜야하는지 파악할 수 있다.
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
|
#include <iostream>
#include <vector>
using namespace std;
struct FenwickTree {
vector<int> tree;
FenwickTree(int n) : tree(n+1, 0) {}
int sum(int pos) {
++pos;
int ret = 0;
while(pos>0) {
ret += tree[pos];
pos&=(pos-1);
}
return ret;
}
void add(int pos, int val) {
++pos;
while(pos < tree.size()) {
tree[pos] += val;
pos += (pos & -pos);
}
}
};
int C, N;
vector<int> A;
long long totalMove() {
long long ret = 0;
FenwickTree tree(1000000);
for(int i = 0; i < A.size(); i++) {
ret += tree.sum(1000000-1) - tree.sum(A[i]);
tree.add(A[i], 1);
}
return ret;
}
int main() {
cin>>C;
while(C--) {
cin>>N;
A.clear();
A.resize(N);
while(N--) {
int tmp;
cin>>tmp;
A.push_back(tmp);
}
cout<<totalMove()<<"\n";
}
}
|
cs |
2. 이진 검색 트리를 이용한 방법
이진 검색또한 균형 잡힌 트리를 이용하여
입력들을 순서대로 정렬 시킨 뒤
주어진 입력 값 보다 작은 원소의 개수를 구해
답을 구한다
이는 균형 잡힌 트리를 구현해야 하므로 펜윜트리보다 구현하기 까다롭다.
3. merge sort를 이용한 방법
merge sort에서 값을 이동시킬때마다 카운트하는 방법이다.
병합 정렬에서는 i < j 인 i,j에서 A[j] < A[i] 일때만 값이 움직다.
따라서 분할하고 정복하는 과정에서
왼쪽 부분 배열A 와 오른쪽 부분 배열 B를 각각 처음부터 비교해나가면서
A[a] > B[b] 인 a 와 b가 될때 a의 오른쪽 끝까지 전부 B[b] 보다 큰 값이므로
이들의 개수를 전부 더한 값이
문제에서 원하는 답이된다.
-알고리즘 문제해결전략 760p
'알고리즘 > 알고리즘 문제 [hard]' 카테고리의 다른 글
[그래프] [2-SAT] [시도 x] MEETINGROOM 회의실 배정 (0) | 2021.02.15 |
---|---|
[그래프] [시도x] WORDCHAIN 단어 제한 끝말잇기 (0) | 2021.02.13 |
[트리] [시도x] FAMILYTREE 족보 탐험 (0) | 2021.02.08 |
[트리] [x]INSERTION 삽입 정렬 뒤집기 (0) | 2021.02.06 |
[트리] [시도 x]FORTRESS 요새 (0) | 2021.02.04 |