All IOI entries
Competitive Programming

IOI 2009 - Garage

This is a direct simulation. Maintain a set<int> of available spots (auto-sorted, smallest first). Maintain a queue<int> of waiting cars. Process each event: Arrival of car c: If a spot is free, assign the smallest; o...

Source sync Apr 19, 2026
Track IOI
Year 2009
Files TeX and C++
Folder competitive_programming/ioi/2009/garage
IOI2009TeXC++

Source-first archive entry

This page is built from the copied files in competitive_programming/ioi/2009/garage. Edit competitive_programming/ioi/2009/garage/solution.tex to update the written solution and competitive_programming/ioi/2009/garage/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

Rendered from the "Problem Statement" section inside solution.tex because this entry has no separate statement file.

A parking garage has $N$ spots with rates $r_1, \ldots, r_N$ (rate per unit weight). There are $M$ cars with weights $w_1, \ldots, w_M$. Cars arrive and depart in a given sequence of $2M$ events. On arrival, a car is assigned the lowest-numbered free spot; if none is free, it waits in a FIFO queue. On departure, the freed spot is offered to the first queued car (which gets the lowest-numbered free spot). The parking fee for a car assigned spot $j$ is $r_j \cdot w_{\text{car}}$. Compute the total revenue.

Editorial

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

Solution

This is a direct simulation.

  1. Maintain a set<int> of available spots (auto-sorted, smallest first).

  2. Maintain a queue<int> of waiting cars.

  3. Process each event:

    • \textbf{Arrival of car $c$}: If a spot is free, assign the smallest; otherwise enqueue.

    • \textbf{Departure of car $c$}: Free its spot. If the queue is non-empty, assign the smallest free spot to the front car.

    • enumerate

    Complexity

    • Time: $O(M \log N)$.

    • Space: $O(N + M)$.

    C++ Solution

    #include <bits/stdc++.h>
    using namespace std;
    
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        int N, M;
        cin >> N >> M;
    
        vector<int> rate(N + 1);
        for(int i = 1; i <= N; i++) cin >> rate[i];
    
        vector<int> weight(M + 1);
        for(int i = 1; i <= M; i++) cin >> weight[i];
    
        set<int> available;
        for(int i = 1; i <= N; i++) available.insert(i);
    
        queue<int> waiting;
        map<int, int> carSpot;
        long long revenue = 0;
    
        for(int e = 0; e < 2 * M; e++){
            int x;
            cin >> x;
            if(x > 0){
                if(!available.empty()){
                    int spot = *available.begin();
                    available.erase(available.begin());
                    carSpot[x] = spot;
                    revenue += (long long)rate[spot] * weight[x];
                } else {
                    waiting.push(x);
                }
            } else {
                int car = -x;
                int spot = carSpot[car];
                carSpot.erase(car);
                available.insert(spot);
                if(!waiting.empty()){
                    int nextCar = waiting.front();
                    waiting.pop();
                    int bestSpot = *available.begin();
                    available.erase(available.begin());
                    carSpot[nextCar] = bestSpot;
                    revenue += (long long)rate[bestSpot] * weight[nextCar];
                }
            }
        }
    
        cout << revenue << "\n";
        return 0;
    }

Code

Exact copied C++ implementation from solution.cpp.

C++ competitive_programming/ioi/2009/garage/solution.cpp

Exact copied implementation source.

Raw file
// IOI 2009 - Garage
// Straightforward simulation with a set of available spots and a FIFO queue.
// O(M log N) time.
#include <bits/stdc++.h>
using namespace std;

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

    int N, M;
    cin >> N >> M;

    vector<int> rate(N + 1);
    for (int i = 1; i <= N; i++) cin >> rate[i];

    vector<int> weight(M + 1);
    for (int i = 1; i <= M; i++) cin >> weight[i];

    // Available spots ordered by number (smallest first).
    set<int> available;
    for (int i = 1; i <= N; i++) available.insert(i);

    queue<int> waiting;          // FIFO queue of cars waiting for a spot
    map<int, int> carSpot;       // car -> assigned spot
    long long revenue = 0;

    int events = 2 * M;
    for (int e = 0; e < events; e++) {
        int x;
        cin >> x;

        if (x > 0) {
            // Car x arrives.
            if (!available.empty()) {
                int spot = *available.begin();
                available.erase(available.begin());
                carSpot[x] = spot;
                revenue += (long long)rate[spot] * weight[x];
            } else {
                waiting.push(x);
            }
        } else {
            // Car -x departs.
            int car = -x;
            int spot = carSpot[car];
            carSpot.erase(car);
            available.insert(spot);

            // Assign the smallest available spot to the next waiting car.
            if (!waiting.empty()) {
                int nextCar = waiting.front();
                waiting.pop();
                int bestSpot = *available.begin();
                available.erase(available.begin());
                carSpot[nextCar] = bestSpot;
                revenue += (long long)rate[bestSpot] * weight[nextCar];
            }
        }
    }

    cout << revenue << "\n";
    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/ioi/2009/garage/solution.tex

Exact copied write-up source.

Raw file
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[margin=1in]{geometry}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{hyperref}

\lstset{
  language=C++,
  basicstyle=\ttfamily\small,
  keywordstyle=\color{blue}\bfseries,
  commentstyle=\color{green!60!black},
  stringstyle=\color{red!70!black},
  numbers=left,
  numberstyle=\tiny\color{gray},
  breaklines=true,
  frame=single,
  tabsize=4,
  showstringspaces=false
}

\title{IOI 2009 -- Garage}
\author{Solution}
\date{}

\begin{document}
\maketitle

\section{Problem Statement}
A parking garage has $N$ spots with rates $r_1, \ldots, r_N$ (rate per unit weight). There are $M$ cars with weights $w_1, \ldots, w_M$. Cars arrive and depart in a given sequence of $2M$ events. On arrival, a car is assigned the lowest-numbered free spot; if none is free, it waits in a FIFO queue. On departure, the freed spot is offered to the first queued car (which gets the lowest-numbered free spot). The parking fee for a car assigned spot $j$ is $r_j \cdot w_{\text{car}}$. Compute the total revenue.

\section{Solution}
This is a direct simulation.
\begin{enumerate}
    \item Maintain a \texttt{set<int>} of available spots (auto-sorted, smallest first).
    \item Maintain a \texttt{queue<int>} of waiting cars.
    \item Process each event:
    \begin{itemize}
        \item \textbf{Arrival of car $c$}: If a spot is free, assign the smallest; otherwise enqueue.
        \item \textbf{Departure of car $c$}: Free its spot. If the queue is non-empty, assign the smallest free spot to the front car.
    \end{itemize}
\end{enumerate}

\subsection{Complexity}
\begin{itemize}
    \item \textbf{Time:} $O(M \log N)$.
    \item \textbf{Space:} $O(N + M)$.
\end{itemize}

\section{C++ Solution}

\begin{lstlisting}
#include <bits/stdc++.h>
using namespace std;

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

    int N, M;
    cin >> N >> M;

    vector<int> rate(N + 1);
    for(int i = 1; i <= N; i++) cin >> rate[i];

    vector<int> weight(M + 1);
    for(int i = 1; i <= M; i++) cin >> weight[i];

    set<int> available;
    for(int i = 1; i <= N; i++) available.insert(i);

    queue<int> waiting;
    map<int, int> carSpot;
    long long revenue = 0;

    for(int e = 0; e < 2 * M; e++){
        int x;
        cin >> x;
        if(x > 0){
            if(!available.empty()){
                int spot = *available.begin();
                available.erase(available.begin());
                carSpot[x] = spot;
                revenue += (long long)rate[spot] * weight[x];
            } else {
                waiting.push(x);
            }
        } else {
            int car = -x;
            int spot = carSpot[car];
            carSpot.erase(car);
            available.insert(spot);
            if(!waiting.empty()){
                int nextCar = waiting.front();
                waiting.pop();
                int bestSpot = *available.begin();
                available.erase(available.begin());
                carSpot[nextCar] = bestSpot;
                revenue += (long long)rate[bestSpot] * weight[nextCar];
            }
        }
    }

    cout << revenue << "\n";
    return 0;
}
\end{lstlisting}

\end{document}