Table of Contents

ExplanationImplementation

Official Analysis (C++)

Explanation

Let posA[i]\texttt{posA}[i] denote the position of cow ii in array A\texttt{A} and posB[i]\texttt{posB}[i] denote the position of cow ii in array B\texttt{B} (where arrays A\texttt{A} and B\texttt{B} represent the two sides of the road). Observe that two cows ii and jj will cross if posA[i]<posA[j]\texttt{posA}[i] < \texttt{posA}[j] and posB[i]>posB[j]\texttt{posB}[i] > \texttt{posB}[j].

We can use the above fact to compute the initial number of crossings. Using an Order Statistics Tree, we can initially store all posB[A[i]]\texttt{posB}[\texttt{A}[i]]. To obtain the number of cows that cross with cow ii, we can erase all posB[A[j]]\texttt{posB}[\texttt{A}[j]] such that j<ij < i and query for the number of elements in the tree that are less than posB[A[i]]\texttt{posB}[\texttt{A}[i]]. To optimize erasing, we can loop from 11 to NN and erase each posB[A[i]]\texttt{posB}[\texttt{A}[i]] before each query.

To handle cyclic shifts, we only care about moving the first cow to the last position. All other crossings will hold constant. Consider shifting array B\texttt{B} to the left:

  • To detach existing crossings from B[1]\texttt{B}[1], we must subtract posA[B[1]]\texttt{posA}[\texttt{B}[1]] because we know for all positions jj such that j<posA[B[1]]j < \texttt{posA}[\texttt{B}[1]], A[j]\texttt{A}[j] is attached to some position B[k]\texttt{B}[k] such that k>1k > 1.
  • Now, B[1]\texttt{B}[1] becomes B[N]\texttt{B}[N]. The number of new crossings is NposA[B[N]]N - \texttt{posA}[\texttt{B}[N]] because we know for all positions jj such that j>posA[B[N]]j > \texttt{posA}[\texttt{B}[N]], A[j]\texttt{A}[j] is attached to some position B[k]\texttt{B}[k] such that k<Nk < N.

Our answer is the minimum crossings out of all cyclic shifts. Note that we may have to consider shifting AA as well.

Implementation

Time Complexity: O(NlogN)\mathcal{O}(N\log N)

C++

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
using ll = long long;
template <typename T>
using ordered_set =
tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

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!