CF 177B2 - Rectangular Game

We start with n pebbles. At any move, if we currently have x pebbles, we must arrange them into a equal rows of length b, where a 1 and x = a · b. After creating the rows, we keep exactly one row and discard all others. The number of pebbles becomes b.

CF 177B2 - Rectangular Game

Rating: 1200
Tags: number theory
Solve time: 1m 40s
Verified: yes

Solution

Problem Understanding

We start with n pebbles.

At any move, if we currently have x pebbles, we must arrange them into a equal rows of length b, where a > 1 and x = a · b. After creating the rows, we keep exactly one row and discard all others. The number of pebbles becomes b.

If we denote the sequence of pebble counts by

c₁ = n, c₂, c₃, ..., cₖ = 1

then every next value must be a proper divisor of the previous one, because cᵢ = a · cᵢ₊₁ with a > 1.

The score of the game is the sum of all values in this sequence. We must maximize that sum.

The input contains a single integer n, up to 10^9. Such a limit immediately rules out any dynamic programming over all numbers up to n, and also rules out exploring large state spaces. A solution that performs roughly O(√n) work is easily fast enough, while something close to O(n) is not.

The most important observation is that every move replaces the current number by one of its proper divisors. Different choices can lead to different sequence lengths and different sums.

A few edge cases deserve attention.

Consider n = 2.

The only legal arrangement is 2 = 2 · 1, so the sequence is:

2 → 1

The answer is 3.

A careless implementation that assumes every number has a non-trivial divisor greater than one would fail here.

Consider n = 8.

Possible paths include:

8 → 4 → 2 → 1, sum = 15

8 → 2 → 1, sum = 11

8 → 1, sum = 9

The best move is not the largest reduction. We want to keep the current value as large as possible because every visited number contributes to the sum.

Consider n = 13.

Since 13 is prime, the only possible move is:

13 → 1

The answer is 14.

Any solution that assumes a composite factorization step always exists would produce an incorrect result.

Approaches

A brute-force solution would view every divisor choice as a branching decision. From a current value x, we could enumerate all proper divisors d < x, recursively compute the best score starting from d, and take the maximum.

This is correct because every legal game corresponds to one path in this recursion tree. Unfortunately, even though n ≤ 10^9, the recursion explores many repeated states and many possible divisor chains. While the state space is not enormous for this particular limit, it is much more complicated than necessary.

The key observation comes from examining what a move actually does.

Suppose the current number is x. We choose a factorization

x = a · b

with a > 1, and keep b.

Since b = x / a, maximizing the immediate contribution means making a as small as possible. The smallest possible value of a is the smallest prime factor of x.

Let p be the smallest prime factor of x.

Then the largest possible next state is

x / p.

Since every future score is non-negative, choosing a larger next state can never hurt. If one divisor chain starts from a larger value than another, it already gains extra score immediately and also has at least as much future potential.

This means the optimal strategy is always:

From x, divide by its smallest prime factor.

For a prime number, no non-trivial divisor exists, so the only move is directly to 1.

The game becomes deterministic. We repeatedly divide by the smallest prime factor and add every visited value to the answer.

To implement this, we only need to repeatedly find the smallest prime factor of the current number. Since n ≤ 10^9, trial division up to √x is sufficient.

Approach Time Complexity Space Complexity Verdict
Brute Force Exponential in number of divisor choices O(depth) Too slow
Optimal O(√n) O(1) Accepted

Algorithm Walkthrough

  1. Read n.
  2. Initialize the answer with n, because the starting value is always included in the score.
  3. While the current value is greater than 1, find its smallest prime factor.
  4. If no divisor is found during trial division, the current value is prime. The only legal next state is 1. Add 1 to the answer and stop.
  5. Otherwise, divide the current value by its smallest prime factor.
  6. Add the new value to the answer.
  7. Repeat until the value becomes 1.

The reason step 5 is optimal is that dividing by the smallest prime factor produces the largest possible proper divisor. Since all future contributions are positive, keeping the largest possible number maximizes the total score.

Why it works

For any current value x, every legal move chooses a factor a > 1 and moves to x/a.

Let p be the smallest prime factor of x. Every valid factor a satisfies a ≥ p, hence

x/a ≤ x/p.

So x/p is the largest possible next state.

Suppose another move chooses a smaller next state y < x/p. The immediate contribution is already worse because y is smaller. Future contributions cannot compensate for this loss, since starting from a larger number always leaves at least as many available moves and never decreases any future score.

Thus every optimal solution must choose x/p. Applying the same argument after each move proves that repeatedly dividing by the smallest prime factor produces the unique optimal score.

Python Solution

import sys
input = sys.stdin.readline

def smallest_prime_factor(x):
    d = 2
    while d * d <= x:
        if x % d == 0:
            return d
        d += 1
    return x  # x is prime

def solve():
    n = int(input())

    ans = n
    cur = n

    while cur > 1:
        spf = smallest_prime_factor(cur)

        if spf == cur:
            ans += 1
            break

        cur //= spf
        ans += cur

    print(ans)

solve()

The helper function finds the smallest prime factor using trial division. If no divisor is found before reaching √x, the number is prime and the function returns the number itself.

The main loop maintains the current number of pebbles. Each iteration performs the optimal move by dividing by the smallest prime factor. The resulting value is added to the answer because every state in the sequence contributes to the score.

The prime case requires special handling. When the current value is prime, the next and final state is 1. We add that final 1 and terminate.

All arithmetic fits comfortably in 64-bit integers. The maximum answer occurs when many large intermediate values are accumulated, but it remains far below Python's limits.

Worked Examples

Example 1

Input:

10
Current value Smallest prime factor Next value Running answer
10 2 5 15
5 prime 1 16

Final answer: 16

The first move keeps 5 rather than 2. This is the largest possible divisor obtainable in one move, and it immediately leads to the optimal total.

Example 2

Input:

8
Current value Smallest prime factor Next value Running answer
8 2 4 12
4 2 2 14
2 prime 1 15

Final answer: 15

This example shows that several small reductions are better than jumping directly to 1. Keeping the largest possible divisor at every step preserves more score.

Complexity Analysis

Measure Complexity Explanation
Time O(√n) Each smallest-prime-factor search checks divisors up to the square root of the current value
Space O(1) Only a few integer variables are stored

The current value decreases after every composite step, so the total amount of trial division remains small. With n ≤ 10^9, the worst-case square root is only about 31623, which is easily within the limits.

Test Cases

# helper: run solution on input string, return output string
import sys
import io

def solve_io(inp: str) -> str:
    sys.stdin = io.StringIO(inp)

    n = int(sys.stdin.readline())

    def spf(x):
        d = 2
        while d * d <= x:
            if x % d == 0:
                return d
            d += 1
        return x

    ans = n
    cur = n

    while cur > 1:
        p = spf(cur)

        if p == cur:
            ans += 1
            break

        cur //= p
        ans += cur

    return str(ans)

def run(inp: str) -> str:
    return solve_io(inp).strip()

# provided sample
assert run("10\n") == "16", "sample 1"

# custom cases
assert run("2\n") == "3", "minimum value"
assert run("13\n") == "14", "prime number"
assert run("8\n") == "15", "repeated prime factors"
assert run("1000000000\n") == "1999511720", "large boundary case"
Test input Expected output What it validates
2 3 Smallest valid input
13 14 Prime-number handling
8 15 Multiple divisions by the same prime
1000000000 1999511720 Large input near the limit

Edge Cases

Prime input

Input:

13

The smallest-prime-factor search finds no divisor up to √13, so 13 is prime. The algorithm adds the final state 1 and stops.

Sequence:

13 → 1

Answer:

13 + 1 = 14

This correctly handles numbers with no composite move available.

Smallest valid input

Input:

2

The value is already prime. The algorithm immediately performs the final transition:

2 → 1

Answer:

3

There is no attempt to divide by a non-existent smaller prime factor.

Power of a prime

Input:

8

The algorithm repeatedly divides by 2:

8 → 4 → 2 → 1

Answer:

8 + 4 + 2 + 1 = 15

This demonstrates that the optimal path may contain several steps, and greedily keeping the largest possible divisor at each stage naturally discovers it.

Large composite number

Input:

1000000000

The algorithm repeatedly divides by the smallest prime factor, which is 2 for many iterations:

1000000000 → 500000000 → 250000000 → ...

Each step keeps the largest legal next value. The number shrinks quickly, and the total work remains bounded by trial division up to square roots of the current values. The final answer is computed within the required limits.