All ICPC entries
Competitive Programming

ICPC 2022 - Q. Doing the Container Shuffle

Containers 1,2,,n are placed independently onto one of two stacks. They are later requested in a fixed order a_1,,a_n. If the next requested container is not on top of its stack, we repeatedly move containers from tha...

Source sync Apr 19, 2026
Track ICPC
Year 2022
Files TeX, C++, statement assets
Folder competitive_programming/icpc/2022/Q-doing-the-container-shuffle
ICPC2022TeXC++statement textstatement pdf

Source-first archive entry

This page is built from the copied files in competitive_programming/icpc/2022/Q-doing-the-container-shuffle. Edit competitive_programming/icpc/2022/Q-doing-the-container-shuffle/solution.tex to update the written solution and competitive_programming/icpc/2022/Q-doing-the-container-shuffle/solution.cpp to update the implementation.

The website does not replace those files with hand-maintained HTML. It reads the copied source tree during the build and exposes the exact files below.

Problem Statement

Copied statement text kept beside the solution archive for direct reference.

World Finals | ICPC 2023 Luxor
     46th Annual                                                                                               hosted by
     ICPC World
   Championship                                                                                                AASTMT

                                           Problem Q
                             Doing the Container Shuffle
                                      Time limit: 2 seconds
Majestic cargo ships, each carrying thousands of shipping con-
tainers, roam the world’s seas every day. They make modern
trade possible by being so efficient that shipping goods halfway
around the world costs only pennies.
Once the ships reach their destination, their standard-size cargo
containers are unloaded from the ship onto stacks on land, from
which they are moved to trains or trucks that deliver them to their
destination. It turns out that moving containers is expensive, so
port operators try to minimize the number of moves necessary
for delivering cargo.                                                  Cargo containers by Martini171 via Wikimedia Commons, cc by-sa

In this problem, we consider such a container-unloading
scenario. We need to unload n containers, which are placed into two stacks built from bottom to top.
The placement of each container is at random, with equal probability it will be put onto the first or the
second stack (independently of other containers). Once all containers are unloaded, they will be picked
up by trucks in a given order. When a truck wants to load a specific container, there are two cases. If
the container is on top of its stack, then the container can be moved to the truck without moving any
other containers. Otherwise, containers have to be moved from one stack to the other until the requested
container is at the top of its stack. At that point the container can be moved onto the truck.
As an example, consider a case of three containers that arrive in order 1, 2, 3. Assume that 1 and 3 are
in the first stack, and 2 is in the second. If the containers are moved onto trucks in order 1, 2, 3, then
five moves of containers have to take place:

                     Stack 1    Stack 2    Comment
                     1 3        2          Initial configuration (stacks bottom to top)
                     1          2 3        Move container 3 from stack 1 to stack 2
                                2 3        Move container 1 to truck
                     3          2          Move container 3 from stack 2 to stack 1
                     3                     Move container 2 to truck
                                           Move container 3 to truck

                   Table Q.1: Example moves of containers requested in order 1 2 3.

We want to know how many moves are necessary to deliver all containers to the customers. Assuming
that container placement is random, we ask you to compute the expected number of moves necessary
for a given truck-loading order.

Input

The first line of input contains an integer n (1 ≤ n ≤ 106 ), the number of containers. The containers are
numbered 1, 2, . . . , n, and are unloaded from the ship in this order. The second line of input contains n
integers a1 , . . . , an . These numbers are a permutation of {1, 2, . . . , n}, and specify the order in which
the containers are loaded onto trucks.

46th ICPC World Championship Problem Q: Doing the Container Shuffle © ICPC Foundation                                             3

                                      World Finals | ICPC 2023 Luxor
     46th Annual                                                                         hosted by
     ICPC World
   Championship                                                                          AASTMT

Output

Output the expected number of moves necessary to load the containers onto the trucks — this excludes
the cost of unloading them from the ship, but includes both moves between stacks and from a stack to a
truck. Your answer should have an absolute error of at most 10−3 .

 Sample Input 1                                     Sample Output 1
 5                                                  7.000
 4 2 5 3 1

 Sample Input 2                                     Sample Output 2
 6                                                  13.500
 1 2 3 4 5 6

46th ICPC World Championship Problem Q: Doing the Container Shuffle © ICPC Foundation                4

Editorial

Rendered from the copied solution.tex file. The original TeX source remains available below.

Key Observations

  • At any moment, the two stacks can be viewed as one joint order: first stack from bottom to top, then second stack from top to bottom. Moving the top container from one stack to the other preserves this joint order; it only changes where the ``cut'' between the two stacks lies.

  • Before unloading $a_{i+1}$, the containers that must be moved are exactly the still-present containers lying in the joint-order interval between $a_i$ and $a_{i+1}$. For $a_1$, the blocking containers are exactly those above $a_1$ on its stack.

  • A container $v$ can lie in that interval only if it was unloaded from the ship after $\min(a_i,a_{i+1})$. For such a container, the random choice of stack puts it in the interval with probability $1/2$.

  • Therefore \[ \mathbb{E}[\text{moves before unloading } a_{i+1}] = \frac{1}{2}\left|\{v : v \text{ is requested after } a_{i+1},\ v > \min(a_i,a_{i+1})\}\right|. \] For the first request $a_1$, the same formula holds with just $v > a_1$.

Algorithm

  1. Start the answer at $n$, since every requested container must eventually be moved from a stack to a truck exactly once.

  2. Process the truck order from right to left, maintaining in a Fenwick tree the set of container labels that appear later in the truck order.

  3. For position $i$:

    • if $i=1$, use threshold $a_1$;

    • otherwise use threshold $\min(a_{i-1},a_i)$.

    • Query how many later-requested containers have label larger than that threshold, divide by $2$, and add it to the answer.

    • Insert $a_i$ into the Fenwick tree and continue. enumerate

      Correctness Proof

      We prove that the algorithm returns the correct answer.

      Lemma 1.

      After any sequence of stack-to-stack moves, the relative order of the containers in the joint order is the same as initially, except that some containers may already have been removed to trucks.

      Proof.

      Moving the top container of one stack to the top of the other stack removes that container from one end of the joint order and inserts it at the other end. The sequence of the remaining containers is unchanged. Removing a requested container simply deletes it from the joint order. Repeating these operations proves the claim.

      Lemma 2.

      Before unloading $a_{i+1}$, the containers that must be moved are exactly the still-present containers in the initial joint-order interval between $a_i$ and $a_{i+1}$.

      Proof.

      By Lemma 1, after $a_i$ has been removed, the still-present containers keep the same relative order as in the initial joint order with already removed containers deleted. To expose $a_{i+1}$, we must move exactly the containers lying between the current cut and $a_{i+1}$, which is the same as the initial interval between $a_i$ and $a_{i+1}$ after deleting already removed containers.

      Lemma 3.

      Fix a later-requested container $v$. It belongs to the interval of Lemma 2 with probability $1/2$ if $v > \min(a_i,a_{i+1})$, and with probability $0$ otherwise.

      Proof.

      If $v < \min(a_i,a_{i+1})$, then $v$ was loaded onto a stack before both endpoints, so it lies below both of them on whichever stack contains it and cannot be between them in the joint order.

      If $v > \min(a_i,a_{i+1})$, then $v$ was loaded later than at least one endpoint. Its random stack choice is independent of all others, and exactly one of the two stack choices places it in the interval between the two endpoints in the initial joint order. Hence the probability is $1/2$.

      Theorem.

      The algorithm outputs the correct expected total number of moves.

      Proof.

      By Lemma 2, the number of stack-to-stack moves before unloading $a_{i+1}$ equals the number of still-present containers in the corresponding interval. By Lemma 3, the expectation of that number is exactly one half of the number of later-requested containers whose labels exceed the threshold $\min(a_i,a_{i+1})$ (or just $a_1$ for the first request). Summing these expectations over all requests and adding the $n$ inevitable truck moves yields exactly the formula computed by the algorithm.

      Complexity Analysis

      Each of the $n$ positions performs one Fenwick query and one update. The running time is $O(n \log n)$ and the memory usage is $O(n)$.

      Implementation Notes

      • The answer is always a multiple of $0.5$, but the implementation prints it as a floating-point number with three digits after the decimal point.

Code

Exact copied C++ implementation from solution.cpp.

C++ competitive_programming/icpc/2022/Q-doing-the-container-shuffle/solution.cpp

Exact copied implementation source.

Raw file
#include <bits/stdc++.h>
using namespace std;

namespace {

struct Fenwick {
    int n = 0;
    vector<int> bit;

    explicit Fenwick(int size) : n(size), bit(size + 1, 0) {}

    void add(int idx, int delta) {
        for (; idx <= n; idx += idx & -idx) {
            bit[idx] += delta;
        }
    }

    int sum_prefix(int idx) const {
        int result = 0;
        for (; idx > 0; idx -= idx & -idx) {
            result += bit[idx];
        }
        return result;
    }
};

void solve() {
    int n;
    cin >> n;

    vector<int> order(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> order[i];
    }

    Fenwick fenwick(n);
    long double answer = static_cast<long double>(n);

    for (int i = n; i >= 1; --i) {
        int threshold = (i == 1 ? order[1] : min(order[i - 1], order[i]));
        int greater = fenwick.sum_prefix(n) - fenwick.sum_prefix(threshold);
        answer += 0.5L * greater;
        fenwick.add(order[i], 1);
    }

    cout << fixed << setprecision(3) << static_cast<double>(answer) << '\n';
}

}  // namespace

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    solve();
    return 0;
}

Source Files

Exact copied source-of-truth files. Edit solution.tex for the write-up and solution.cpp for the implementation.

TeX write-up competitive_programming/icpc/2022/Q-doing-the-container-shuffle/solution.tex

Exact copied write-up source.

Raw file
\documentclass[11pt]{article}
\usepackage[margin=1in]{geometry}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{enumitem}

\title{ICPC World Finals 2022\\Q. Doing the Container Shuffle}
\author{}
\date{}

\begin{document}
\maketitle

\section*{Problem Summary}

Containers $1,2,\dots,n$ are placed independently onto one of two stacks. They are later requested in a
fixed order $a_1,\dots,a_n$. If the next requested container is not on top of its stack, we repeatedly move
containers from that stack to the other stack until it is exposed. We must compute the expected total
number of moves, including the final move from a stack to a truck.

\section*{Key Observations}

\begin{itemize}[leftmargin=*]
    \item At any moment, the two stacks can be viewed as one \emph{joint order}:
    first stack from bottom to top, then second stack from top to bottom.
    Moving the top container from one stack to the other preserves this joint order; it only changes where
    the ``cut'' between the two stacks lies.
    \item Before unloading $a_{i+1}$, the containers that must be moved are exactly the still-present
    containers lying in the joint-order interval between $a_i$ and $a_{i+1}$. For $a_1$, the blocking
    containers are exactly those above $a_1$ on its stack.
    \item A container $v$ can lie in that interval only if it was unloaded from the ship after
    $\min(a_i,a_{i+1})$. For such a container, the random choice of stack puts it in the interval with
    probability $1/2$.
    \item Therefore
    \[
    \mathbb{E}[\text{moves before unloading } a_{i+1}]
    = \frac{1}{2}\left|\{v : v \text{ is requested after } a_{i+1},\ v > \min(a_i,a_{i+1})\}\right|.
    \]
    For the first request $a_1$, the same formula holds with just $v > a_1$.
\end{itemize}

\section*{Algorithm}

\begin{enumerate}[leftmargin=*]
    \item Start the answer at $n$, since every requested container must eventually be moved from a stack
    to a truck exactly once.
    \item Process the truck order from right to left, maintaining in a Fenwick tree the set of container
    labels that appear later in the truck order.
    \item For position $i$:
    \begin{itemize}[leftmargin=*]
        \item if $i=1$, use threshold $a_1$;
        \item otherwise use threshold $\min(a_{i-1},a_i)$.
    \end{itemize}
    \item Query how many later-requested containers have label larger than that threshold, divide by $2$,
    and add it to the answer.
    \item Insert $a_i$ into the Fenwick tree and continue.
\end{enumerate}

\section*{Correctness Proof}

We prove that the algorithm returns the correct answer.

\paragraph{Lemma 1.}
After any sequence of stack-to-stack moves, the relative order of the containers in the joint order is the
same as initially, except that some containers may already have been removed to trucks.

\paragraph{Proof.}
Moving the top container of one stack to the top of the other stack removes that container from one end of
the joint order and inserts it at the other end. The sequence of the remaining containers is unchanged.
Removing a requested container simply deletes it from the joint order. Repeating these operations proves
the claim. \qed

\paragraph{Lemma 2.}
Before unloading $a_{i+1}$, the containers that must be moved are exactly the still-present containers in
the initial joint-order interval between $a_i$ and $a_{i+1}$.

\paragraph{Proof.}
By Lemma 1, after $a_i$ has been removed, the still-present containers keep the same relative order as in
the initial joint order with already removed containers deleted. To expose $a_{i+1}$, we must move exactly
the containers lying between the current cut and $a_{i+1}$, which is the same as the initial interval
between $a_i$ and $a_{i+1}$ after deleting already removed containers. \qed

\paragraph{Lemma 3.}
Fix a later-requested container $v$. It belongs to the interval of Lemma 2 with probability $1/2$ if
$v > \min(a_i,a_{i+1})$, and with probability $0$ otherwise.

\paragraph{Proof.}
If $v < \min(a_i,a_{i+1})$, then $v$ was loaded onto a stack before both endpoints, so it lies below both
of them on whichever stack contains it and cannot be between them in the joint order.

If $v > \min(a_i,a_{i+1})$, then $v$ was loaded later than at least one endpoint. Its random stack choice is
independent of all others, and exactly one of the two stack choices places it in the interval between the
two endpoints in the initial joint order. Hence the probability is $1/2$. \qed

\paragraph{Theorem.}
The algorithm outputs the correct expected total number of moves.

\paragraph{Proof.}
By Lemma 2, the number of stack-to-stack moves before unloading $a_{i+1}$ equals the number of
still-present containers in the corresponding interval. By Lemma 3, the expectation of that number is
exactly one half of the number of later-requested containers whose labels exceed the threshold
$\min(a_i,a_{i+1})$ (or just $a_1$ for the first request). Summing these expectations over all requests and
adding the $n$ inevitable truck moves yields exactly the formula computed by the algorithm. \qed

\section*{Complexity Analysis}

Each of the $n$ positions performs one Fenwick query and one update. The running time is
$O(n \log n)$ and the memory usage is $O(n)$.

\section*{Implementation Notes}

\begin{itemize}[leftmargin=*]
    \item The answer is always a multiple of $0.5$, but the implementation prints it as a floating-point
    number with three digits after the decimal point.
\end{itemize}

\end{document}