Number Of Inversion

Theory

What is Inversion??

한국어로는 역전이라고도 한다.
배열 $A=Array$ 에 대해 $i, j$ 는 $0 <= i,j<= length(A)$ 이다.

  • 역전은 아래를 만족함.
    • $A[i] < A[j]$

다시말해, Number of Inversion 은 이 역전의 개수를 세는 문제이다.

How to count Number of Inversion?

필자는 Merge sort로 구현하는 아이디어를 떠올렸다. 정렬하는 과정에서 카운팅 하는 것이 쉽다는 힌트를 보고 왜 그런가 정말 오래 고민했다.

아무튼, Merge Sort를 할 때는 항상 아래의 과정을 따른다.

각 요소를 합치는 과정에서 가장 작은것부터 비교가 이루어지며, $Array2$에서 이를 활용해 만약 $Array1$의 다음으로 선택할 가장 작은 요소가, $Array2$의 그것보다 크다면, $Array1$의 남은 요소 수 만큼 역전 쌍이 상기게 된다.

여기까지 다다르고 나면, 머지소트로 어떻게 구현해야 하는지 감이 올 것이다.

Sample code

백준 1517 버블 소트번이 적절한 문제로 보여, 해당 문제의 solution중 일부를 담았다.

#include <iostream>
#include <vector>
using namespace std;

int n;
vector<int>v,tmp;
long long cnt;

void merge(int s, int e) {
    int mid = (s + e) / 2;
    int i = s, j = mid + 1, k = s;
    while (i <= mid && j <= e) {
        if (v[i] > v[j]) { // There is an Inversion! 
            cnt+=mid-i+1;
            tmp[k++] = v[j++];
        }
        else {
            tmp[k++] = v[i++];
        }
    }
    while (i <= mid)tmp[k++] = v[i++];
    while (j <= e)tmp[k++] = v[j++];
    for (int p = s; p <= e; p++)v[p] = tmp[p];
}

void partition(int s, int e) {  // s to e-1
    if (s >= e)return;
    int mid = (s + e) / 2;
    partition(s, mid);
    partition(mid + 1, e);
    merge(s, e);
}

'Study Notes > PS' 카테고리의 다른 글

[LCA] 최소 공통 조상 알고리즘  (0) 2025.07.10
[2636] 치즈  (0) 2025.06.29
[1744] 수 묶기  (0) 2025.06.27
[10453] 문자열 변환  (0) 2025.06.26

댓글