This blog's target audience is for newbies who don't know this (like me!). So, if you knew this before, it would be great if you read this blog and give me some valuable feedbacks. Thanks ^^!
Now for the intro:
A while ago, I met a problem where it requires me to count the number of inversion of an array. Having 2 braincells, I knew nothing about this. So, I decided to ask my friends ballss and quanhoangbla. Of course, they are good friends so they taught me everything about that. NO. ballss just called me dumb, so I decided to learn it myself. That's when I stumbled across this blog. This blog, in my opinion, is a great blog, but it was not really well written. As a result, it got heavily downvoted (I recommend you upvote that blog, although it's most likely that the author have stopped doing CP, since the last time he/she visited was 9 months ago). Although I understand the main idea, I think that it might be confusing for other newbies too. So, I decided to rewrite that blog, to understand about this topic more and to contribute to the community :D.
Also, as you can notice from the title, this is the first part of this series. If I'm not lazy, I may write some more parts. If you want me to rewrite a blog, you can DM me for that topic.
NOTE THAT ALL OF THE IDEAS IN THIS BLOG WERE FROM THIS BLOG. WHAT I DO IS JUST REWRITE THAT BLOG SO THAT IT'S EASIER TO UNDERSTAND
Now, for the main part of the blog:
Counting inversion using mergesort/fenwick tree
Problem statement:
You were given an array $$$a$$$ of size $$$n$$$ $$$(1 ≤ n ≤ 10^5,$$$ $$$a_i ≤ 10^5$$$ $$$\forall$$$ $$$1 ≤ i ≤ n)$$$. Count the number of inversion in this array.
Naive approach: Brute force
Since the constraint of $$$n$$$ is up to $$$10^5$$$, so this approach will certainly get TLE. Tho, I think it's good to have this part so that you can understand the correct solution better.
The main idea of this method is to use 2 for loops to iterate through all of the possible pair of index. Then, you check if they sastify the condition. If yes, increase the count by 1.
Time complexity: $$$O(n^2)$$$
Space complexity: $$$O(n)$$$
Solution 1: Using Mergesort
It is recommended to read this blog to know more about merge sort
For the main idea of this method:
You need to count the number of inversions in the array $$$a$$$. You split them into 2 halves: array $$$b$$$ and $$$c$$$ (array $$$b$$$ contains the first half of array $$$a$$$, and array $$$c$$$ contains the second half). Assume that you have the inversion count for array $$$b$$$ and $$$c$$$. So, to get the inversion count of array $$$a$$$, you need to add the number of inversions in array $$$b$$$, array $$$c$$$, and the cross inversions (the number of index $$$i$$$ and $$$j$$$ so that, $$$i$$$ is in array $$$b$$$, $$$j$$$ is in array $$$c$$$ and $$$a_i \gt a_j$$$. This is an inversion since $$$i \lt j$$$). Think how to count this.
Time complexity: $$$O(n$$$ $$$log$$$ $$$n)$$$
Space complexity: $$$O(n)$$$
Solution 2: Using Fenwick tree
It is recommended to read this blog to understand what is Fenwick tree. Explaining this is quite long so, for the sake of simplicity, assume that you know how fenwick tree works (by reading the blog I recommended) ^^
The main idea of this algorithm is, you build a frequency array, let's call it $$$freq$$$. Then, $$$freq_i$$$ will be the number of times that $$$i$$$ appeared. So, the number of indexes that are less than are equal to $$$i$$$ would be
Where $$$prefix_i$$$ is the prefix sum of the first $$$i$$$ elements in array $$$freq$$$. You can get this value in $$$log$$$ $$$n$$$ time using fenwick tree.
So, to count the number of inversions in an array $$$a$$$, initially, we set the array $$$freq$$$ to $$$0$$$. Then, you would need to iterate $$$x$$$ in array $$$a$$$ from back to front. After that, you add the numbers of indexes that are less than $$$a_x$$$ to the answer, which is the $$$prefix_{a_x - 1}$$$ to the array. This can be done in $$$log$$$ $$$n$$$ time. Note that you add $$$prefix_{a_x - 1}$$$, not $$$prefix_{a_x}$$$ since you need to count the number of elements that are less than $$$a_x$$$, not less than or equal to $$$a_x$$$.
Finally, you update the $$$freq_{a_x}$$$ by one. This mean that, you need to update the $$$prefix$$$ array as well. This can also be done in $$$log$$$ $$$n$$$ time using fenwick tree.
Time complexity: $$$O(n$$$ $$$log$$$ $$$n)$$$
Space complexity: $$$O(n)$$$
Bonus (this isn't in the original blog):
As you can see, the fenwick tree can only store elements that are less than are equal to $$$10^7$$$ (since that's the memory limit for an array in C++, I don't know for other languages). So, if the problem gives you $$$a_i$$$ up to $$$10^{18}$$$, what would you do? Of course, you can still use merge sort, but fenwick tree is way easier to implement.
So, that's the end of the blog! This is my first time posting something useful (as the others are mostly shitposts -_-), so I hope that you like this. Also, if you want me to rewrite any blog, message me. (Of course, please send me a blog that I can understand, not a FFT blog...).
Thank you for reading, and have a nice day ;)









Why does the naive approach have to TLE?
(lol sorry we just did this today so its fresh in my mind. and yes it appears intended given that TL was set to 15 sec...)
link dont works
Order statistic tree works too
tf is that :skull:
also known as ordered set, can import it from pbds library