JOI 2013 - Bubblesort

Author: Andi Qu

Intuition

In this problem, we're asked to find the maximum decrease in the number of inversions of the array.

Firstly, unless the array is already sorted, we can always decrease the number of inversions. We can also assume that we only ever swap aia_i and aja_j (i<ji < j) if ai>aja_i > a_j. (Could you prove this formally?)

After playing around with some swaps and arrays, we find that the only array elements that contribute to that change if we swap aia_i and aja_j (i<ji < j) are the aka_k such that ikji \leq k \leq j and aiakaja_i \geq a_k \geq a_j.

This condition feels similar to the inequalities defining a rectangle. Could we possibly find a geometric interpretation of this problem?

Turning the Problem into Geometry

Plot the points (i,ai)(i, a_i) on the Cartesian plane.

Notice how if we swap aia_i and aja_j (i<ji < j), the change in the number of inversions is equal to:

(No. of points strictly inside the rectangle (i,ai,j,aj))+(No. of points in or on the rectangle (i,ai,j,aj))1(\text{No. of points strictly inside the rectangle }(i, a_i, j, a_j)) + (\text{No. of points in or on the rectangle }(i, a_i, j, a_j)) - 1

From this, we also find that if we have x<yx < y and axaya_x \geq a_y, then yy can't be the left index in the optimal swap.

This means that we can simply consider a set of ii with strictly increasing aia_i as candidates for the left index in the optimal swap!

Using the D&C Optimization

Let optiopt_i be the index such that if we must swap aia_i with something to its right, then swapping it with aoptia_{opt_i} is optimal.

Since aia_i is strictly increasing in our set of candidates, we can prove that optiopti1opt_i \geq opt_{i - 1} for all ii in our set.

This means that we can use the D&C optimization to find all optiopt_i!

We can use a BIT or any other suitable data structure to query the number of points in a rectangle efficiently.

Implementation

Time Complexity: O(Nlog2N)\mathcal{O}(N \log^2 N)

Memory Complexity: O(N)\mathcal{O}(N)

#include <bits/stdc++.h>
#define FOR(i, x, y) for (int i = x; i < y; i++)
typedef long long ll;
using namespace std;
ll ans = 0, bit[100001];
int n, a[100001], b[100001];
vector<int> cand;
void update(int pos, ll val) {

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!