이전에도 비슷한 문제가 있었던것 같은데.
Inversion Count 수 구하기...
Swap의 개수를 구하는 문제와 동일한 형태로.
기본 코드는 아래와 같다.
static int getInversionCnt(int[] A, int n) {
int inv_cnt = 0;
for(int i=0; i<n-1 ; i++){
for(int j=i+1 ; j<n ; j++) {
if(A[i] > A[j] {
inv_cnt++;
}
}
}
return inv_cnt;
}
위 코드는 기본 Sorting 시 숫자를 세는 거고, 변경 위치를 세는 경우, 다른 방식을 사용해야 함.
관련 문제가 백준에 있어 링크한다.
https://www.acmicpc.net/problem/7578
케이블의 교차수를 세는 문제지만, 펜윅트리(BIT) 혹은 세그먼트 트리로 풀수 있음.
교차점에 따른 모든점을 계산할 필요 없이, 앞에서 부터 이동하는 위치의 거리만 계산해주면 됨.
문제를 푸는 방법은
1. 펜윅트리를 만든다. 초기값은 모두 0
2. 1~n까지 탐색을하며 B에서의 나의 위치 뒤에있는 것의 합을 더한다!
3. 그리고 나의 위치를 트리에서 1로 바꿔준다
교차점의 수를 세는 것이므로 A의 앞에있던 공장이 B에서는 뒤에있다면 교차점이 생긴다. 그래서 뒤에 1이 몇개있는지만 세어주면 된다!
눈뜬 장님이었네..ㅠㅠ
import java.io.*;
import java.util.StringTokenizer;
public class Factory {
static int N;
static int[] P, NE;
static int[] PT;
static void update(int h, int v, int[] PT) {
for (int i = h; i <= N ; i+=(i&-i)) PT[i] += v;
}
static long query(int h, int[] PT) {
long result = 0;
for (int i = h; i > 0 ; i-=(i&-i)) result += PT[i];
return result;
}
public static void main(String[] args) throws IOException {
System.setIn(new FileInputStream("res/factory_input.txt"));
long Start = System.currentTimeMillis();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st1, st2;
int T = Integer.parseInt(br.readLine().trim());
for (int t = 1; t <= T ; t++) {
N = Integer.parseInt(br.readLine().trim());
P = new int[N+1];
NE = new int[200001];
PT = new int[N+1];
st1 = new StringTokenizer(br.readLine().trim(), " ");
st2 = new StringTokenizer(br.readLine().trim(), " ");
for (int i = 1; i <= N ; i++) {
P[i] = Integer.parseInt(st1.nextToken());
NE[Integer.parseInt(st2.nextToken())] = i;
}
long result = 0;
for (int i = 1; i <= N ; i++) {
result += query(N, PT) - query(NE[P[i]], PT);
update(NE[P[i]], 1, PT);
}
System.out.println("#"+t+" "+result);
}
System.out.println("Total : " + (System.currentTimeMillis()-Start) + " ms");
}
}