Source: IMOSLC-2023-P4
Category: Extremal Problems

Problem: Given an integer $n\\geq2$. Paul has a $1\\times n^2$ strip of paper, with squares labeled $1, 2, \\cdots, n^2$ in order. Paul wants to cut the strip into $m$ consecutive segments such that, after translating these segments (rotation and flipping are not allowed), they can form an $n\\times n$ grid. In this grid, for each $1\\leq i,j\\leq n$, the number $a_{i,j}$ in the $i$-th row and $j$-th column satisfies $a_{i,j}\\equiv i+j-1\\pmod{n}$. If Paul can achieve this, find the minimum value of $m$.

Answer: 2n-1

Reference solution:
It suffices to work modulo $n$. In this case, the numbers on the tape are $1, 2, \dots, n$ repeated $n$ times, and the target grid table is given by $a_{i,j} \equiv i+j-1 \pmod n$:
$$
\def\arraystretch{1.5}
\begin{array}{|c|c|c|c|c|}
\hline
1 & 2 & \cdots & n-1 & n \\ \hline
2 & 3 & \cdots & n & 1 \\ \hline
\vdots & \vdots & \ddots & \vdots & \vdots \\ \hline
n & 1 & \cdots & n-2 & n-1 \\ \hline
\end{array}
$$

**Construction for $m = 2n-1$:**
Cut the tape into $2n-1$ pieces whose lengths, in order, are $n, 1, n-1, 2, n-2, \dots, n-1, 1$. 
Specifically, the first piece has length $n$. For $2 \le i \le n$, the $(2i-2)$-th piece has length $i-1$ and the $(2i-1)$-th piece has length $n-i+1$. 

Because the tape consists of repeating blocks of $1, 2, \dots, n$, the first piece is exactly $1, 2, \dots, n$. For $2 \le i \le n$, the $(2i-2)$-th piece starts at the beginning of a block and thus contains $1, 2, \dots, i-1$, while the $(2i-1)$-th piece contains the remainder of that block, $i, i+1, \dots, n$.

Use the first piece as the first row of the grid table. For $2 \le i \le n$, swap the $(2i-2)$-th piece with the $(2i-1)$-th piece to form the $i$-th row of the grid table. This places $i, i+1, \dots, n$ followed by $1, 2, \dots, i-1$, which exactly matches the $i$-th row of the grid. Hence, this cutting satisfies the requirement.

**Lower bound $m \ge 2n-1$:**
Construct a directed graph $G$ whose vertices are $1, 2, \dots, n$. For each of the $m$ segments, if the numbers on the segment are $a, a+1, \dots, b-1 \pmod n$, add a directed edge from $a$ to $b$. The graph $G$ has a total of $m$ edges, allowing multiple edges and loops. 

Since the segments are contiguous on the tape, the end of one segment is immediately followed by the start of the next segment. Thus, the sequence of $m$ segments forms a continuous walk. Since the tape starts at $1$ and ends at $n \equiv 0 \pmod n$, the walk starts at $1$ and ends at $1$, meaning the whole tape corresponds to an Eulerian circuit of $G$. Because the tape contains all $n$ numbers, $G$ is connected and spans all $n$ vertices.

The $i$-th row of the grid is formed by a sequence of segments that starts at $i$ and ends at $i-1 \pmod n$. Thus, the edges corresponding to the segments of the $i$-th row form a directed cycle (or loop) in $G$ that starts and ends at vertex $i$. Since there are $n$ rows, the $m$ edges of $G$ can be partitioned into $n$ such cycles.

Observe that deleting one edge from a cycle leaves a path that still connects all the vertices of that cycle. Therefore, after deleting one edge from each of the $n$ cycles corresponding to the rows, the vertex set of each cycle remains connected. Since the original graph $G$ is the connected union of these cycles, the remaining graph remains connected and spans all $n$ vertices. 

At this point, the connected spanning subgraph must have at least $n-1$ edges. Since we deleted exactly $n$ edges (one from each row's cycle), the total number of edges in $G$ must be at least $n + (n-1) = 2n-1$. 

Hence, the minimum value of $m$ is $2n-1$.

Grading guidelines:
(Partial) 1. Gave the construction achieving m=2n-1 (e.g. cut lengths n,1,n-1,2,n-2,...,n-1,1) and correctly explained how to place the pieces row-by-row to obtain rows i,i+1,...,n,1,...,i-1 modulo n. 2. Reduced the problem to working modulo n (tape is 1,2,...,n repeated n times; target grid is the cyclic Latin square a_{i,j}≡i+j-1 (mod n)), and used this to justify that each row must be formed from a cyclic shift of 1,2,...,n. 3. Set up a valid lower-bound framework by encoding each segment as an edge a→b in a directed multigraph on {1,...,n} (where the segment reads a,a+1,...,b-1 mod n), and observed that the segments in each row correspond to a directed cycle. (Almost) 1. Proved m≥2n-1 via the directed-graph/cycle decomposition idea, and gave the construction for m=2n-1, but left a small gap in justifying that after deleting one edge from each row-cycle the remaining spanning subgraph is still connected (or equivalently that the union of the resulting paths must connect all n vertices). 2. Completed the lower bound m≥2n-1 except for a localized issue in translating the geometry of the grid into the statement that the m edges can be partitioned into n cycles (one per row), or in the argument that the graph spans all n vertices. 3. Solution is almost complete, but made minor mistakes which are not negligible.

Construction task:
For the specific case $n=150$, provide an explicit construction of the segments and their arrangement that achieves the minimum number of segments $m$.

Construction format requirements:
- Output a single Python dictionary with two keys: `'endpoints'` and `'rows'`.
- `'endpoints'` must be a list of strictly increasing positive integers $a_1 < a_2 < \dots < a_m = 150^2$, representing the endpoints of the segments. The $k$-th segment contains the numbers from $a_{k-1} + 1$ to $a_k$ (with $a_0 = 0$).
- `'rows'` must be a list of 150 lists. The $i$-th list specifies the order of segments used to form the $i$-th row of the grid. Segments are 1-indexed (i.e., $1, 2, \dots, m$).
- The total number of segments $m$ must be the minimum possible for $n=150$.
- The resulting $150 \times 150$ grid must satisfy the condition $a_{i,j} \equiv i+j-1 \pmod{150}$ for all $1 \le i, j \le 150$.
- Put ONLY the Python expression inside the construction block. The expression will be evaluated using `eval()` to obtain the dictionary, so you may use list comprehensions to keep the output compact. Do not include any imports, assignments, or markdown formatting.

Reference construction:
{"endpoints": [150] + [val for i in range(2, 151) for val in ((i-1)*150 + i - 1, i*150)], "rows": [[1]] + [[2*i - 1, 2*i - 2] for i in range(2, 151)]}

Verifier code:
import sys

def verify():
    raw_str = sys.stdin.read().strip()
    if not raw_str:
        print("Empty input")
        return

    try:
        data = eval(raw_str)
    except Exception as e:
        print(f"Failed to parse input with eval: {e}")
        return

    if type(data) is not dict:
        print("Parsed object is not a dictionary")
        return
    
    if set(data.keys()) != {'endpoints', 'rows'}:
        print("Dictionary must contain exactly the keys 'endpoints' and 'rows'")
        return

    endpoints = data['endpoints']
    rows = data['rows']

    if type(endpoints) is not list:
        print("'endpoints' is not a list")
        return
    
    if len(endpoints) != 299:
        print(f"'endpoints' must have exactly 299 elements, got {len(endpoints)}")
        return
    
    if endpoints[-1] != 22500:
        print(f"The last element of 'endpoints' must be 22500, got {endpoints[-1]}")
        return
    
    prev = 0
    for i, val in enumerate(endpoints):
        if type(val) is not int:
            print(f"Element at index {i} in 'endpoints' is not an integer")
            return
        if val <= prev:
            print(f"'endpoints' must be strictly increasing positive integers, but found {prev} followed by {val}")
            return
        prev = val

    if type(rows) is not list:
        print("'rows' is not a list")
        return
    
    if len(rows) != 150:
        print(f"'rows' must have exactly 150 lists, got {len(rows)}")
        return
    
    seen_segments = set()
    for i, r in enumerate(rows, 1):
        if type(r) is not list:
            print(f"Row {i} in 'rows' is not a list")
            return
        for idx in r:
            if type(idx) is not int:
                print(f"Segment index {idx} in row {i} is not an integer")
                return
            if idx < 1 or idx > 299:
                print(f"Segment index {idx} in row {i} is out of bounds (1 to 299)")
                return
            if idx in seen_segments:
                print(f"Segment index {idx} appears more than once")
                return
            seen_segments.add(idx)
            
    if len(seen_segments) != 299:
        missing = set(range(1, 300)) - seen_segments
        print(f"Not all segment indices from 1 to 299 are used. Missing: {missing}")
        return

    segments = {}
    prev = 0
    for k, val in enumerate(endpoints, 1):
        segments[k] = list(range(prev + 1, val + 1))
        prev = val

    grid = []
    for i, r in enumerate(rows, 1):
        row_elements = []
        for idx in r:
            row_elements.extend(segments[idx])
        if len(row_elements) != 150:
            print(f"Reconstructed row {i} does not have exactly 150 elements (has {len(row_elements)})")
            return
        grid.append(row_elements)

    for i in range(150):
        for j in range(150):
            val = grid[i][j]
            expected = (i + 1 + j + 1 - 1) % 150
            if val % 150 != expected:
                print(f"Grid element at row {i+1}, col {j+1} is {val}, which is {val % 150} mod 150, expected {expected}")
                return

    print("True")

if __name__ == "__main__":
    verify()