Official

G - Constrained Nim 2 Editorial by en_translator


The Grundy number is a prerequisite of this editorial. If you do not know it, see an editorial of a past ABC problem. (Similar problem: ABC255-G)

In a game problem, experimenting is always a good idea.

In this problem too, we can expect that the Grundy number \(f(x)\) of \(x\) is

\[\lfloor \frac{x\bmod {(L+R)}}{L}\big\rfloor.\]

If this conjecture is true, then this problem can be solved in a total of \(\mathrm{O}(N)\) time. (A sample code comes later.)

We now show that this conjecture is true.

(1) If \(x < L+R\)

  • If \(0\leq x <L\), a move cannot be made, so \(f(x)=0\).

  • If \(L\leq x <2L\), then \(x-R < L\) since \(x < L+R\), so one can transition to a state whose Grundy number is \(0\). Additionally, \( x - L < L\), so one cannot transition to a state whose Grundy number is \(1\). Thus, \(f(x)=1\).

  • If \(2L\leq x <3L\), then \(x-R < L\) since \(x < L+R\), so one can transition to a state whose Grundy number is \(0\). Moreover, \(L\leq x - L < 2L\) since \(2L \leq x < 3L\), so one can also transition to a state whose Grundy number is \(1\). On the other hand, \( x -L<2L\), so one cannot transition to a state whose Grundy number is \(2\). Thus, \(f(x)=2\).

By repeating the discussion above, we can show that \(f(x)=\lfloor \frac{x}{L}\big\rfloor\) for \(x<L+R\).

(2) If \( L+R\leq x < 2(L+R)\)

  • If \(L+R\leq x < L+R+L\), then \(L\leq x-R<2L\) thus \(R\leq x-L<L+R\), so one cannot transition to a state whose Grundy number is \(0\). Thus, \(f(x)=0\).

  • If \(L+R+L\leq x < L+R+2L\), by the same discussion, one can transition to a state whose Grundy number is \(0\) but not to \(1\). Thus, \(f(x)=1\).

The same discussion holds for all \(x\) such that \( L+R\leq x < 2(L+R)\). Thus, for \( L+R\leq x < 2(L+R)\), it holds that \(f(x)=\lfloor \frac{x\bmod {(L+R)}}{L}\big\rfloor\).

(3) In general case

If \(2(L+R)\leq x\), then the Grundy number \(f(x)\) depends only on \(f(x-R),f(x-R+1),\ldots,f(x-L)\) in our case. By (2), in general we have \(f(x)=\lfloor \frac{x\bmod {(L+R)}}{L}\big\rfloor\).


Sample code (C++):

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

int f(int x, int l, int r) {
    return (x % (l + r)) / l;
}

bool solve(vector<int>& v, int l, int r) {
    int fold = 0;
    for(const auto u : v) fold ^= f(u, l, r);
    return fold != 0;
}

int main() {
    int n, l, r;
    cin >> n >> l >> r;
    vector<int> a(n);
    for(auto& v : a) cin >> v;
    cout << (solve(a, l, r) ? "First\n" : "Second\n");
}

posted:
last update: