All ICPC entries
Competitive Programming

ICPC 2024 - C. Citizenship

For an application date A, the previous y years are the y consecutive intervals [A-365, A-1], [A-730, A-366],, [A-365y, A-365(y-1)-1]. In each such interval we must have been present at least d days, which is equivale...

Source sync Apr 19, 2026
Track ICPC
Year 2024
Files TeX, C++, statement assets
Folder competitive_programming/icpc/2024/C-citizenship
ICPC2024TeXC++statement textstatement pdf

Source-first archive entry

This page is built from the copied files in competitive_programming/icpc/2024/C-citizenship. Edit competitive_programming/icpc/2024/C-citizenship/solution.tex to update the written solution and competitive_programming/icpc/2024/C-citizenship/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.

Problem C
                                            Citizenship
                                      Time limit: 4 seconds
It has been a long time since you moved to a different country and you
have decided it is time to become a citizen. Your new country has a
strict residency requirement for all applicants. To apply, you must have
been physically present in the country for at least d days per year, for the
past y consecutive years. These years are counted in 12-month periods
backwards from the application date.
For this problem, assume that a calendar year has 12 months of 365                            Image via Rawpixel, CC0
days, and each month has exactly the number of days below:

                  month    01    02    03   04    05   06    07    08   09     10   11   12
                   days    31    28    31   30    31   30    31    31   30     31   30   31

For example, if you were to apply on 2024–09–19 you must have been in the country for at least d days
during the 12-month periods from 2023–09–19 to 2024–09–18, 2022–09–19 to 2023–09–18, and so on
for y such periods.
You have lived in the country for at least y years, but having traveled a lot, you are not sure if you meet
the residency requirement. Write a program that finds the earliest date you can submit your citizenship
application given your travel history.

Input

The first line contains three integers n, y and d (1 ≤ n ≤ 500, 1 ≤ y ≤ 1 000, 1 ≤ d ≤ 365). You have
been out of the country n times and y and d specify the country’s residency requirement as described
above.
Each of the following n lines contains two dates in the form YYYY-MM-DD (0000 ≤ YYYY ≤ 5 000,
01 ≤ MM ≤ 12, 01 ≤ DD ≤ 31). You have been out of the country between the two dates, inclusive.
All dates in the input are sorted in increasing order. The only dates which may be equal are dates on the
same line. All given dates are valid.

Output

Output the earliest date on which you meet the residency requirement. The date must be after the last
date of the input.

 Sample Input 1                                         Sample Output 1
 3 5 240                                                2024-05-31
 2022-02-28 2022-10-01
 2022-11-11 2022-11-11
 2023-12-30 2024-01-01

48th ICPC World Championship Problem C: Citizenship © ICPC Foundation                                             5

Sample Input 2                                Sample Output 2
3 5 240                                       2028-02-26
2011-11-11 2012-12-12
2022-02-28 2022-10-01
2025-01-01 2025-06-30

48th ICPC World Championship Problem C: Citizenship © ICPC Foundation   6

Editorial

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

Key Observations

  • The only thing that matters about a date is its position modulo $365$. For a fixed residue $r = A \bmod 365$, the relevant 12-month periods are aligned to a fixed partition of the timeline into blocks of length $365$.

  • Therefore there are only $365$ possible alignments to check.

  • For one fixed residue $r$, define block $b$ as \[ [r + 365b,\; r + 365b + 364]. \] The application date $A = r + 365t$ is valid exactly when blocks $t-y, t-y+1, \dots, t-1$ are all good, where a block is good if it contains at most $365-d$ absent days.

  • The absence intervals are few, but the total date range is still small enough: at most about $5000 \cdot 365 + 1001 \cdot 365$. A plain prefix-sum over days is easily fast enough.

Algorithm

  1. Convert every calendar date to an integer day number using the fixed 365-day calendar.

  2. Mark all absent days with a difference array and build a prefix sum of absent days.

  3. Let $L$ be the last day in the input. It is enough to search up to $L + 365(y+1)$, because after that all $y$ required years lie completely after the last trip and are therefore automatically valid.

  4. For each residue $r \in \{0,\dots,364\}$:

    1. Scan the 365-day blocks with that alignment.

    2. For each block, compute its absent-day count in $O(1)$ from the prefix sum and decide whether the block is good.

    3. Maintain the current run length of consecutive good blocks.

    4. As soon as the run length reaches $y$, the application date immediately after the last block in that run is valid. If it is after $L$, update the global minimum answer.

    5. Convert the minimum day number back to YYYY-MM-DD.

    Correctness Proof

    We prove that the algorithm outputs the earliest valid application date.

    Lemma 1.

    For a fixed residue $r$, an application date $A \equiv r \pmod{365}$ is valid if and only if the $y$ consecutive 365-day blocks immediately before $A$ in the $r$-aligned partition are all good.

    Proof.

    Write $A = r + 365t$. Then \[ [A-365, A-1] = [r + 365(t-1),\; r + 365t - 1], \] which is exactly block $t-1$. Similarly, the next earlier year is block $t-2$, and so on down to block $t-y$. So the $y$ periods required by the statement are exactly the $y$ consecutive blocks immediately before $A$. Each period is valid exactly when its absent-day count is at most $365-d$.

    Lemma 2.

    For a fixed residue $r$, when the scan first finds a run of at least $y$ consecutive good blocks ending at block $b$, the date $A = r + 365(b+1)$ is the earliest valid application date with residue $r$.

    Proof.

    By Lemma 1, $A$ is valid because the preceding $y$ blocks are good. Any earlier date with the same residue has the form $r + 365t$ with $t \le b$. Its preceding $y$ blocks must therefore end at some block strictly before $b$. Since $b$ is the first point where the scan sees $y$ consecutive good blocks, no such earlier date can be valid.

    Lemma 3.

    There exists a valid application date no later than $L + 365(y+1)$, where $L$ is the last day in the input.

    Proof.

    Consider any date $A > L + 365y + 364$. Then the earliest of the $y$ required periods starts at $A - 365y > L$. So all $y$ required 365-day periods lie completely after the last recorded trip and contain zero absent days. Hence they are all valid.

    Theorem.

    The algorithm outputs the earliest valid application date after the last input date.

    Proof.

    By Lemma 3, the search range always contains at least one valid date. For each residue class, Lemma 2 gives the earliest valid date with that residue. Taking the minimum over all 365 residues therefore yields the earliest valid date overall.

    Complexity Analysis

    Let $T$ be the number of days scanned. Here \[ T = O(5000 \cdot 365 + y \cdot 365), \] which is at most about $2.2 \cdot 10^6$.

    Building the difference array and prefix sums takes $O(T + n)$. The 365 residue scans together also process only $O(T)$ blocks. Thus the total running time is $O(T + n)$ and the memory usage is $O(T)$.

    Implementation Notes

    • Since the calendar is fixed and has no leap years, date conversion is just base-365 arithmetic with the given month lengths.

    • The output must be after the last date in the input, so the candidate date must satisfy $A > L$.

    • Difference arrays handle inclusive absence intervals cleanly: add $+1$ at the start day and $-1$ at the day after the end.

Code

Exact copied C++ implementation from solution.cpp.

C++ competitive_programming/icpc/2024/C-citizenship/solution.cpp

Exact copied implementation source.

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

namespace {

constexpr int MONTHS = 12;
constexpr int YEAR_DAYS = 365;
const int MONTH_LEN[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int day_of_year(int month, int day) {
    int ans = 0;
    for (int i = 0; i < month - 1; ++i) {
        ans += MONTH_LEN[i];
    }
    return ans + day - 1;
}

int parse_date(const string& s) {
    const int year = stoi(s.substr(0, 4));
    const int month = stoi(s.substr(5, 2));
    const int day = stoi(s.substr(8, 2));
    return year * YEAR_DAYS + day_of_year(month, day);
}

string format_date(int serial) {
    const int year = serial / YEAR_DAYS;
    int rem = serial % YEAR_DAYS;
    int month = 1;
    while (rem >= MONTH_LEN[month - 1]) {
        rem -= MONTH_LEN[month - 1];
        ++month;
    }
    const int day = rem + 1;

    ostringstream out;
    out << setw(4) << setfill('0') << year << '-'
        << setw(2) << setfill('0') << month << '-'
        << setw(2) << setfill('0') << day;
    return out.str();
}

void solve() {
    int n, y, d;
    cin >> n >> y >> d;
    const int max_absent = YEAR_DAYS - d;
    const int history_shift = YEAR_DAYS * y;

    vector<pair<int, int>> trips(n);
    int last_day = 0;
    for (int i = 0; i < n; ++i) {
        string l, r;
        cin >> l >> r;
        trips[i] = {parse_date(l) + history_shift, parse_date(r) + history_shift};
        last_day = max(last_day, trips[i].second);
    }

    const int limit = last_day + YEAR_DAYS * (y + 1);
    vector<int> diff(limit + 2, 0);
    for (const auto& trip : trips) {
        ++diff[trip.first];
        --diff[trip.second + 1];
    }

    vector<int> absent(limit + 1, 0);
    vector<int> pref(limit + 2, 0);
    int cur = 0;
    for (int day = 0; day <= limit; ++day) {
        cur += diff[day];
        absent[day] = (cur > 0 ? 1 : 0);
        pref[day + 1] = pref[day] + absent[day];
    }

    int answer = limit;
    for (int residue = 0; residue < YEAR_DAYS; ++residue) {
        int run = 0;
        for (int block = 0; residue + block * YEAR_DAYS + YEAR_DAYS - 1 <= limit; ++block) {
            const int start = residue + block * YEAR_DAYS;
            const int finish = start + YEAR_DAYS - 1;
            const int days_absent = pref[finish + 1] - pref[start];
            if (days_absent <= max_absent) {
                ++run;
            } else {
                run = 0;
            }

            if (run >= y) {
                const int apply_day = residue + (block + 1) * YEAR_DAYS;
                if (apply_day > last_day) {
                    answer = min(answer, apply_day);
                    break;
                }
            }
        }
    }

    cout << format_date(answer - history_shift) << '\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/2024/C-citizenship/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 2024\\C. Citizenship}
\author{}
\date{}

\begin{document}
\maketitle

\section*{Problem Summary}

For an application date $A$, the previous $y$ years are the $y$ consecutive intervals
\[
[A-365, A-1], [A-730, A-366], \dots, [A-365y, A-365(y-1)-1].
\]
In each such interval we must have been present at least $d$ days, which is equivalent to being absent at
most $365-d$ days. We must output the earliest valid application date after the last recorded trip.

\section*{Key Observations}

\begin{itemize}[leftmargin=*]
    \item The only thing that matters about a date is its position modulo $365$. For a fixed residue
    $r = A \bmod 365$, the relevant 12-month periods are aligned to a fixed partition of the timeline into
    blocks of length $365$.
    \item Therefore there are only $365$ possible alignments to check.
    \item For one fixed residue $r$, define block $b$ as
    \[
        [r + 365b,\; r + 365b + 364].
    \]
    The application date $A = r + 365t$ is valid exactly when blocks
    $t-y, t-y+1, \dots, t-1$ are all good, where a block is good if it contains at most $365-d$ absent days.
    \item The absence intervals are few, but the total date range is still small enough: at most about
    $5000 \cdot 365 + 1001 \cdot 365$. A plain prefix-sum over days is easily fast enough.
\end{itemize}

\section*{Algorithm}

\begin{enumerate}[leftmargin=*]
    \item Convert every calendar date to an integer day number using the fixed 365-day calendar.
    \item Mark all absent days with a difference array and build a prefix sum of absent days.
    \item Let $L$ be the last day in the input. It is enough to search up to
    $L + 365(y+1)$, because after that all $y$ required years lie completely after the last trip and are
    therefore automatically valid.
    \item For each residue $r \in \{0,\dots,364\}$:
    \begin{enumerate}[leftmargin=*]
        \item Scan the 365-day blocks with that alignment.
        \item For each block, compute its absent-day count in $O(1)$ from the prefix sum and decide
        whether the block is good.
        \item Maintain the current run length of consecutive good blocks.
        \item As soon as the run length reaches $y$, the application date immediately after the last block in
        that run is valid. If it is after $L$, update the global minimum answer.
    \end{enumerate}
    \item Convert the minimum day number back to \texttt{YYYY-MM-DD}.
\end{enumerate}

\section*{Correctness Proof}

We prove that the algorithm outputs the earliest valid application date.

\paragraph{Lemma 1.}
For a fixed residue $r$, an application date $A \equiv r \pmod{365}$ is valid if and only if the $y$
consecutive 365-day blocks immediately before $A$ in the $r$-aligned partition are all good.

\paragraph{Proof.}
Write $A = r + 365t$. Then
\[
[A-365, A-1] = [r + 365(t-1),\; r + 365t - 1],
\]
which is exactly block $t-1$. Similarly, the next earlier year is block $t-2$, and so on down to block
$t-y$. So the $y$ periods required by the statement are exactly the $y$ consecutive blocks immediately
before $A$. Each period is valid exactly when its absent-day count is at most $365-d$. \qed

\paragraph{Lemma 2.}
For a fixed residue $r$, when the scan first finds a run of at least $y$ consecutive good blocks ending at
block $b$, the date $A = r + 365(b+1)$ is the earliest valid application date with residue $r$.

\paragraph{Proof.}
By Lemma 1, $A$ is valid because the preceding $y$ blocks are good. Any earlier date with the same
residue has the form $r + 365t$ with $t \le b$. Its preceding $y$ blocks must therefore end at some block
strictly before $b$. Since $b$ is the first point where the scan sees $y$ consecutive good blocks, no such
earlier date can be valid. \qed

\paragraph{Lemma 3.}
There exists a valid application date no later than $L + 365(y+1)$, where $L$ is the last day in the input.

\paragraph{Proof.}
Consider any date $A > L + 365y + 364$. Then the earliest of the $y$ required periods starts at
$A - 365y > L$. So all $y$ required 365-day periods lie completely after the last recorded trip and contain
zero absent days. Hence they are all valid. \qed

\paragraph{Theorem.}
The algorithm outputs the earliest valid application date after the last input date.

\paragraph{Proof.}
By Lemma 3, the search range always contains at least one valid date. For each residue class, Lemma 2
gives the earliest valid date with that residue. Taking the minimum over all 365 residues therefore yields
the earliest valid date overall. \qed

\section*{Complexity Analysis}

Let $T$ be the number of days scanned. Here
\[
T = O(5000 \cdot 365 + y \cdot 365),
\]
which is at most about $2.2 \cdot 10^6$.

Building the difference array and prefix sums takes $O(T + n)$. The 365 residue scans together also
process only $O(T)$ blocks. Thus the total running time is $O(T + n)$ and the memory usage is $O(T)$.

\section*{Implementation Notes}

\begin{itemize}[leftmargin=*]
    \item Since the calendar is fixed and has no leap years, date conversion is just base-365 arithmetic with
    the given month lengths.
    \item The output must be \emph{after} the last date in the input, so the candidate date must satisfy
    $A > L$.
    \item Difference arrays handle inclusive absence intervals cleanly: add $+1$ at the start day and $-1$
    at the day after the end.
\end{itemize}

\end{document}