All IOI entries
Competitive Programming

IOI 2022 - Insects

Step 1: Count distinct types Insert insects one by one. After each insertion, if press\_button() > 1, remove the insect (it is a duplicate). The number of insects remaining in the machine equals the number of distinct...

Source sync Apr 19, 2026
Track IOI
Year 2022
Files TeX and C++
Folder competitive_programming/ioi/2022/insects
IOI2022TeXC++

Source-first archive entry

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

There are $N$ insects, each of some unknown type. A machine supports three operations:

  • $\texttt{move\_inside}(i)$: place insect $i$ in the machine.

  • $\texttt{move\_outside}(i)$: remove insect $i$ from the machine.

  • $\texttt{press\_button}()$: return the maximum frequency among all types currently in the machine.

  • Determine the cardinality of the rarest insect type.

Editorial

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

Solution

Step 1: Count distinct types

Insert insects one by one. After each insertion, if $\texttt{press\_button}() > 1$, remove the insect (it is a duplicate). The number of insects remaining in the machine equals the number of distinct types $d$. Then clear the machine.

This step uses at most $2N$ operations ($N$ insertions + at most $N$ removals + $N$ button presses + $d$ removals to clear).

Step 2: Binary search on the answer

Binary search on $k \in [1, \lfloor N/d \rfloor]$, testing whether the minimum type frequency is at most $k$.

Check for a given $k$.

Insert insects one by one, rejecting any insect whose insertion would cause $\texttt{press\_button}() > k$. After processing all $N$ insects, the machine contains exactly $\min(k, \mathrm{count}(t))$ insects of each type $t$. The total inside is $T = \sum_t \min(k, \mathrm{count}(t))$.

If $T < d \cdot k$, then some type has fewer than $k$ insects, so the minimum frequency is $\le k$. Otherwise every type has count $\ge k$ and we set $\mathrm{lo} = k + 1$.

Each check uses $O(N)$ operations. The binary search has $O(\log(N/d))$ iterations.

Total operation count

$O(N \log(N/d))$ operations overall. For the IOI limits ($N \le 2000$), this is at most roughly $2000 \times 11 \approx 22000$, well within the allowed budget.

Implementation

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

void move_inside(int i);
void move_outside(int i);
int press_button();

int min_cardinality(int N) {
    // Step 1: count distinct types
    vector<bool> inside(N, false);
    int num_types = 0;
    for (int i = 0; i < N; i++) {
        move_inside(i);
        if (press_button() > 1) {
            move_outside(i);
        } else {
            inside[i] = true;
            num_types++;
        }
    }
    // Clear the machine
    for (int i = 0; i < N; i++)
        if (inside[i]) {
            move_outside(i);
            inside[i] = false;
        }

    // Step 2: binary search on the rarest frequency
    int lo = 1, hi = N / num_types;
    while (lo < hi) {
        int mid = (lo + hi) / 2;

        // Check: is the minimum frequency <= mid?
        int total_inside = 0;
        vector<bool> in_machine(N, false);
        for (int i = 0; i < N; i++) {
            move_inside(i);
            if (press_button() > mid) {
                move_outside(i);
            } else {
                in_machine[i] = true;
                total_inside++;
            }
        }

        bool has_rare = (total_inside < (long long)num_types * mid);

        // Clean up
        for (int i = 0; i < N; i++)
            if (in_machine[i])
                move_outside(i);

        if (has_rare)
            hi = mid;
        else
            lo = mid + 1;
    }
    return lo;
}

Complexity

  • Operations: $O(N \log(N/d))$ where $d$ is the number of distinct types. Each binary-search iteration uses $O(N)$ move/press calls.

  • Space: $O(N)$.

Code

Exact copied C++ implementation from solution.cpp.

C++ competitive_programming/ioi/2022/insects/solution.cpp

Exact copied implementation source.

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

// Grader functions
void move_inside(int i);
void move_outside(int i);
int press_button();

int min_cardinality(int N) {
    // Step 1: Find number of distinct types
    vector<bool> inside(N, false);
    int num_types = 0;

    for (int i = 0; i < N; i++) {
        move_inside(i);
        if (press_button() > 1) {
            move_outside(i);
        } else {
            inside[i] = true;
            num_types++;
        }
    }

    // Clear machine
    for (int i = 0; i < N; i++)
        if (inside[i]) {
            move_outside(i);
            inside[i] = false;
        }

    // Step 2: Binary search on answer k
    int lo = 1, hi = N / num_types;

    while (lo < hi) {
        int mid = (lo + hi) / 2;

        // Check: is minimum frequency <= mid?
        // Add insects allowing at most 'mid' per type
        int total_inside = 0;
        vector<bool> in_machine(N, false);

        for (int i = 0; i < N; i++) {
            move_inside(i);
            total_inside++;
            if (press_button() > mid) {
                move_outside(i);
                total_inside--;
            } else {
                in_machine[i] = true;
            }
        }

        // If total_inside < num_types * mid, some type has < mid insects
        bool has_rare = (total_inside < (long long)num_types * mid);

        // Clean up
        for (int i = 0; i < N; i++)
            if (in_machine[i]) {
                move_outside(i);
                in_machine[i] = false;
            }

        if (has_rare) {
            hi = mid;
        } else {
            lo = mid + 1;
        }
    }

    return lo;
}

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/2022/insects/solution.tex

Exact copied write-up source.

Raw file
\documentclass[11pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{amsmath,amssymb,amsthm}
\usepackage{listings}
\usepackage{geometry}
\usepackage{hyperref}
\geometry{margin=2.5cm}

\newtheorem{theorem}{Theorem}
\newtheorem{lemma}[theorem]{Lemma}

\lstset{
  language=C++,
  basicstyle=\ttfamily\small,
  keywordstyle=\bfseries,
  breaklines=true,
  numbers=left,
  numberstyle=\tiny,
  frame=single,
  tabsize=2
}

\title{IOI 2022 --- Insects}
\author{}
\date{}

\begin{document}
\maketitle

\section{Problem Statement}

There are $N$ insects, each of some unknown type.  A machine supports
three operations:
\begin{itemize}
  \item $\texttt{move\_inside}(i)$: place insect $i$ in the machine.
  \item $\texttt{move\_outside}(i)$: remove insect $i$ from the machine.
  \item $\texttt{press\_button}()$: return the maximum frequency among all
        types currently in the machine.
\end{itemize}
Determine the cardinality of the rarest insect type.

\section{Solution}

\subsection{Step 1: Count distinct types}

Insert insects one by one.  After each insertion, if
$\texttt{press\_button}() > 1$, remove the insect (it is a duplicate).
The number of insects remaining in the machine equals the number of
distinct types~$d$.  Then clear the machine.

This step uses at most $2N$ operations ($N$ insertions + at most $N$ removals
+ $N$ button presses + $d$ removals to clear).

\subsection{Step 2: Binary search on the answer}

Binary search on $k \in [1, \lfloor N/d \rfloor]$, testing whether the
minimum type frequency is at most $k$.

\paragraph{Check for a given $k$.}
Insert insects one by one, rejecting any insect whose insertion would
cause $\texttt{press\_button}() > k$.  After processing all $N$ insects, the
machine contains exactly $\min(k, \mathrm{count}(t))$ insects of each type~$t$.
The total inside is $T = \sum_t \min(k, \mathrm{count}(t))$.

If $T < d \cdot k$, then some type has fewer than $k$ insects, so the
minimum frequency is $\le k$.  Otherwise every type has count $\ge k$
and we set $\mathrm{lo} = k + 1$.

Each check uses $O(N)$ operations.  The binary search has
$O(\log(N/d))$ iterations.

\subsection{Total operation count}

$O(N \log(N/d))$ operations overall.  For the IOI limits
($N \le 2000$), this is at most roughly $2000 \times 11 \approx 22000$,
well within the allowed budget.

\section{Implementation}

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

void move_inside(int i);
void move_outside(int i);
int press_button();

int min_cardinality(int N) {
    // Step 1: count distinct types
    vector<bool> inside(N, false);
    int num_types = 0;
    for (int i = 0; i < N; i++) {
        move_inside(i);
        if (press_button() > 1) {
            move_outside(i);
        } else {
            inside[i] = true;
            num_types++;
        }
    }
    // Clear the machine
    for (int i = 0; i < N; i++)
        if (inside[i]) {
            move_outside(i);
            inside[i] = false;
        }

    // Step 2: binary search on the rarest frequency
    int lo = 1, hi = N / num_types;
    while (lo < hi) {
        int mid = (lo + hi) / 2;

        // Check: is the minimum frequency <= mid?
        int total_inside = 0;
        vector<bool> in_machine(N, false);
        for (int i = 0; i < N; i++) {
            move_inside(i);
            if (press_button() > mid) {
                move_outside(i);
            } else {
                in_machine[i] = true;
                total_inside++;
            }
        }

        bool has_rare = (total_inside < (long long)num_types * mid);

        // Clean up
        for (int i = 0; i < N; i++)
            if (in_machine[i])
                move_outside(i);

        if (has_rare)
            hi = mid;
        else
            lo = mid + 1;
    }
    return lo;
}
\end{lstlisting}

\section{Complexity}

\begin{itemize}
  \item \textbf{Operations:} $O(N \log(N/d))$ where $d$ is the number of
        distinct types.  Each binary-search iteration uses $O(N)$
        move/press calls.
  \item \textbf{Space:} $O(N)$.
\end{itemize}

\end{document}