출처 : https://www.acmicpc.net/problem/1517
inversion counting

나는 merge sort tree 모른다.

아래 풀이는 segment tree 사용

#include<stdio.h>
#include<malloc.h>
struct info
{
	int idx;
	long long val;
};
long long answer, * tree;
struct info *list, *sorted;
void msort(struct info *, int, int);
void merge(struct info *, int, int, int);
int cmp(struct info, struct info);
long long qu(int, int, int, int, int);
void update(int);
long long make_answer();
int main(void)
{
	answer = make_answer();
	printf("%lld\n", answer);
	return 0;
}
long long make_answer()
{
	int n, l, r, g, s, e, node, i;
	long long ans;
	scanf("%d", &n);
	for (list = (struct info*)malloc(sizeof(struct info) * n), sorted = (struct info*)malloc(sizeof(struct info) * n), s = node = l = r = 1; r - l + 1 < n; l <<= 1, r <<= 1, r |= 1);
	for (tree = (long long *)calloc(r + 1, sizeof(long long)), i = 0, g = l - 1, e = r - l + 1; i < n; i++)
	{
		scanf("%lld", &list[i].val);
		list[i].idx = i + 1;
		tree[i + 1 + g] = 1;
	}
	for (i = g; i; i--)
	{
		tree[i] = tree[i << 1] + tree[i << 1 | 1];
	}
	msort(list, 0, n - 1);
	for (i = 0, ans = 0; i < n; i++)
	{
		ans += qu(node, s, e, 1, list[i].idx - 1);
		update(list[i].idx + g);
	}
	free(tree);
	free(list);
	free(sorted);
	return ans;
}
void msort(struct info * list, int left, int right)
{
	int mid;
	if (left < right)
	{
		mid = (left + right) >> 1;
		msort(list, left, mid);
		msort(list, mid + 1, right);
		merge(list, left, mid, right);
	}
}
void merge(struct info * list, int left, int mid, int right)
{
	int i, j, k, l;
	i = k = left;
	j = mid + 1;
	while (i <= mid && j <= right)
	{
		if (cmp(list[i], list[j]))
		{
			sorted[k++] = list[i++];
		}
		else
		{
			sorted[k++] = list[j++];
		}
	}
	if (mid < i)
	{
		for (l = j; l <= right; l++)
		{
			sorted[k++] = list[l];
		}
	}
	else
	{
		for (l = i; l <= mid; l++)
		{
			sorted[k++] = list[l];
		}
	}
	for (l = left; l <= right; l++)
	{
		list[l] = sorted[l];
	}
}
int cmp(struct info a, struct info b)
{
	return a.val <= b.val;
}
long long qu(int node, int start, int end, int left, int right)
{
	int mid;
	if (left > end || right < start)
	{
		return 0;
	}
	else if (left <= start && end <= right)
	{
		return tree[node];
	}
	mid = (start + end) >> 1;
	return qu(node << 1, start, mid, left, right) + qu(node << 1 | 1, mid + 1, end, left, right);
}
void update(int idx)
{
	tree[idx] = 0;
	idx >>= 1;
	while (idx)
	{
		tree[idx] = tree[idx << 1] + tree[idx << 1 | 1];
		idx >>= 1;
	}
}