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: