#include "vision.h"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
int dis(int i1, int j1, int i2, int j2) {
return abs(i1-i2) + abs(j1-j2);
}
map<int, int> diagr; // abajo izq a arriba der
map<int, int> diagl; //abajo der a arriba izq;
int S;
void atmostk(int H, int W, int k) {
//Ya tengo la informacion de las diagonales owo
//bloques de k+1 diagonales abajo izq a arriba der.
vector<int> digr;
for (int i=0; i<=H+W-2; i++) {
if (i+k > H+W-2) continue;
vector<int> Ns;
for (int j=i; j<=i+k; j++) {
Ns.push_back(diagr[j]);
}
add_xor(Ns);//S
add_not(S);//S+1
for (auto &x : Ns) {
x++;
}
add_or(Ns); //S+2
vector<int> aux = {S+1, S+2};
add_and(aux); //Esto sera 1 si y solo si hay 2 bloques en el conjunto de bloques owo
digr.push_back(S+3);
S += 4;
}
//Bloques de k+1 diagonales abajo der a arriba izq;
vector<int> digl;
for (int i=-(W-1); i<=H-1; i++) {
if (i+k > H-1) continue;
vector<int> Ns;
for (int j=i; j<=i+k; j++) {
Ns.push_back(diagl[j]);
}
add_xor(Ns);//S
add_not(S);//S+1
for (auto &x : Ns) {
x++;
}
add_or(Ns); //S+2
vector<int> aux = {S+1, S+2};
add_and(aux);
digl.push_back(S+3);
S += 4;
}
//Juntar
add_or(digr); //S
add_or(digl); //S+1
vector<int> aux = {S, S+1};
add_and(aux); //S+2
S += 3;
}
void construct_network(int H, int W, int k) {
S = H*W;
//Diagonales abajo izq
diagl.clear();
diagr.clear();
for (int i=0; i<=H+W-2; i++) {
vector<int> Ns;
for (int i1=0; i1<H; i1++) {
for (int j=0; j<W; j++) {
if (i1+j == i) {
int id = i1*W+j;
Ns.push_back(id);
}
}
}
diagr[i] = S;
add_xor(Ns); //S
add_or(Ns);
S += 2;
}
//Diagonales abajo der
for (int i=-(W-1); i<=H-1; i++) {
vector<int> Ns;
for (int i1=0; i1<H; i1++) {
for (int j=0; j<W; j++) {
if (i1-j == i) {
int id = i1*W + j;
Ns.push_back(id);
}
}
}
diagl[i] = S;
add_xor(Ns);//S
add_or(Ns);//S+1
S += 2;
}
if (k==1) {
atmostk(H, W, k);
}
else {
atmostk(H, W, k);
int beg = S-1;
atmostk(H, W, k-1);
vector<int> aux = {beg, S};
add_not(S-1); //S
add_and(aux);
}
}