xortransform
Explicación
Tras ejecutar la solución de fuerza bruta, se puede observar que el período de cómo se ve la matriz es la menor potencia de dos que es mayor que y que .
Además, podemos reducir el problema a hallar la xor-suma de los elementos en posiciones tales que el número de caminos de a en pasos es impar, donde es el número de transformaciones hechas.
Esto es igual a , donde es sobre . Además, si es impar, entonces (esto también se puede observar por fuerza bruta).
Además, si y son impares, entonces también es impar, así que podemos reducir el problema a SOS DP, donde = xor-suma de los elementos que están en posiciones incluidas por .
Para cada bit del período, , si tiene el bit en esa posición igual a .
Para otros enfoques, también se pueden ver las soluciones de usuarios en Infoarena ; solo hay que pulsar el popup que aparece al hacer clic por primera vez en una solución. Hay que tener en cuenta que la versión usada es ligeramente distinta de la versión real, ya que este problema se dio como problema interactivo e Infoarena no podía soportar problemas interactivos en ese momento.
Implementación para la versión de Infoarena
Complejidad temporal:
#include <bits/stdc++.h>
using namespace std;
int main() {
ifstream f("xortransform.in");
int n, m, q;
f >> n >> m >> q;
vector<int> sos(n * m * 2 + 1);
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int nr;
f >> nr;
sos[i | j] ^= nr;
}
}
int mx = 1;
int stp = 1;
while (mx < n || mx < m) {
mx <<= 1;
stp++;
}
for (int i = 0; i < stp; i++) {
for (int j = 0; j < mx; j++) {
if (j & (1 << i)) { sos[j] ^= sos[j - (1 << i)]; }
}
}
int prev_ans = 0;
ofstream g("xortransform.out");
for (int i = 0; i < q; i++) {
int nr;
f >> nr;
nr ^= prev_ans;
nr &= (mx - 1);
prev_ans = sos[nr];
g << prev_ans << '\n';
}
}