Explanation
Notice that can only be swapped with no matter which operations are performed.
For all such that (we only need to consider each pair once and keeping will ensure this), we can determine whether we want to swap them or keep them the same.
If , we want to swap them. If we want to keep them the same. If they are equal it doesn't matter.
However, it is possible that not all conditions can work together with each other and swapping something/keeping something the same means we can't swap something else/keep something the same later on. Consider the following input:
0 2 1 1 0 1 3 2 0
We want to first swap and because is less than . We can do this by flipping the th row/col. This would give us the array:
0 1 3 2 0 1 1 2 0
Then we want to swap and because is less than . To do this either we can either swap the th row/col or the nd row/col. However, swapping the th row/col would undo the efforts of our first operation so we will swap the nd row/col and get:
0 1 1 2 0 2 3 1 0
Now we want to swap and because is less than and we want the lexicographically minimum. However swapping the st row/col would mess up the swap we made in the first operation and swapping the nd row/col would mess up the swap we made in the second operation. Thus, it is impossible to make all swaps optimally.
Since we want the lexicographically smallest answer, the earlier indices matter more than later indices so we find optimal row swaps for earlier indices first.
We can create a disjoint set union to model this problem. The DSU will have nodes where node represents the state where the operation is performed on the th row and node represents the state where operation is not performed on the th row.
As we are iterating greedily through the array, we can merge ( and ) and ( and ) if we don't want to swap. This works because if we swap neither or swap both the arrangement remains the same. If we do want to swap we can merge ( and ) and ( and ). This works because if we swap exactly one of these, then the arrangement will change.
After this we can construct the answer by iterating over each cell of the grid. If the cell's row index is equal to its column index (i.e. it's on the diagonal of the grid) it can never change regardless of the flips. If then we can manually set them (since we didn't merge them in the disjoint set union when comparing them the states might have not been merged). Otherwise, we can check whether and are merged in the disjoint set union. If they aren't then we will swap and . Otherwise we will keep them the same.
Implementation
Time Complexity:
C++
#include <iostream>#include <vector>using namespace std;Code Snippet: DSU (Click to expand)void solve() {int n;cin >> n;
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!