Problem p02704 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

#define cerr                                                                   \
  if (false)                                                                   \
  cerr

struct Edge {
  int u, v;
  int cap, flow;

  Edge(int u_, int v_, int cap_, int flow_)
      : u(u_), v(v_), cap(cap_), flow(flow_) {}
};

const int N = 501;
const int LIM = N * N;

namespace MaxFlow {
const int INF = 1e9 + 239;
const int MAX_LOG = 1;

int n;
int start;
int end;

int d[LIM];
int pnt[LIM];
vector<int> g[LIM];

vector<Edge> ed;

int dfs(int u, int flow) {
  if (flow == 0) {
    return 0;
  }
  if (u == end) {
    return flow;
  }
  for (; pnt[u] < (int)g[u].size(); pnt[u]++) {
    int ind = g[u][pnt[u]];
    int to = ed[ind].v;
    if (d[to] < d[u] + 1) {
      continue;
    }
    int pushed = dfs(to, min(flow, ed[ind].cap - ed[ind].flow));
    if (pushed > 0) {
      ed[ind].flow += pushed;
      ed[ind ^ 1].flow -= pushed;
      return pushed;
    }
  }
  return 0;
}

bool bfs(int lim) {
  for (int i = 0; i < n; i++) {
    d[i] = INF;
  }
  d[start] = 0;
  queue<int> q;
  q.push(start);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (auto ind : g[u]) {
      int to = ed[ind].v;
      if (d[to] > d[u] + 1 && ed[ind].flow + lim <= ed[ind].cap) {
        d[to] = d[u] + 1;
        q.push(to);
      }
    }
  }
  return d[end] < INF;
}

void init(int n_, int start_, int end_) {
  n = n_;
  start = start_;
  end = end_;
  ed.clear();
  fill(d, d + n, 0);
  fill(pnt, pnt + n, 0);
  for (int i = 0; i < n; i++) {
    g[i].clear();
  }
}

int add_edge(int u, int v, int c) {
  assert(u < n);
  assert(v < n);
  int pnt_ed = (int)ed.size();
  ed.push_back(Edge(u, v, c, 0));
  ed.push_back(Edge(v, u, 0, 0));
  g[u].push_back(pnt_ed);
  g[v].push_back(pnt_ed + 1);
  return pnt_ed;
}

int solve() {
  int ans = 0;
  for (int i = MAX_LOG; i >= 0; i--) {
    while (bfs(1LL << i)) {
      fill(pnt, pnt + n, 0);
      while (true) {
        int nw = dfs(start, INF);
        if (nw > 0) {
          ans += nw;
        } else {
          break;
        }
      }
    }
  }
  return ans;
}
}; // namespace MaxFlow

int s[N];
int t[N];
int ub[N];
int vb[N];
int tans[N][N];

int solve_bit(int n) {
  int all_ok = 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      tans[i][j] = -1;
    }
  }
  auto safe_set = [&](int i, int j, int val) {
    if (tans[i][j] != -1 && tans[i][j] != val) {
      all_ok = 0;
    }
    tans[i][j] = val;
  };
  vector<int> need_row(n, -1);
  vector<int> need_col(n, -1);
  for (int i = 0; i < n; i++) {
    if (s[i] == 0 && ub[i] == 1) {
      // cerr << "R " << i << ' ' << 0 << endl;
      for (int j = 0; j < n; j++) {
        safe_set(i, j, 1);
      }
    } else if (s[i] == 1 && ub[i] == 0) {
      // cerr << "R " << i << ' ' << 1 << endl;
      for (int j = 0; j < n; j++) {
        safe_set(i, j, 0);
      }
    } else {
      if (s[i] == 0) {
        need_row[i] = 0;
      } else {
        need_row[i] = 1;
      }
    }
  }
  for (int j = 0; j < n; j++) {
    if (t[j] == 0 && vb[j] == 1) {
      for (int i = 0; i < n; i++) {
        safe_set(i, j, 1);
      }
    } else if (t[j] == 1 && vb[j] == 0) {
      for (int i = 0; i < n; i++) {
        safe_set(i, j, 0);
      }
    } else {
      if (t[j] == 0) {
        need_col[j] = 0;
      } else {
        need_col[j] = 1;
      }
    }
  }

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (tans[i][j] == -1 && need_row[i] != -1 && need_row[i] == need_col[j]) {
        cerr << "ADD " << i << ' ' << j << endl;
        safe_set(i, j, need_row[i]);
      }
      if (tans[i][j] != -1) {
        if (tans[i][j] == need_row[i]) {
          need_row[i] = -1;
        }
        if (tans[i][j] == need_col[j]) {
          need_col[j] = -1;
        }
      }
    }
  }
  {
    cerr << "need_row: " << endl;
    for (auto x : need_row) {
      cerr << x << ' ';
    }
    cerr << endl;
  }

  {
    cerr << "need_col: " << endl;
    for (auto x : need_col) {
      cerr << x << ' ';
    }
    cerr << endl;
  }
  if (!all_ok) {
    return 0;
  }
  cerr << "HR " << endl;
  vector<pair<int, int>> iv;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (tans[i][j] == -1) {
        cerr << "EMP " << i << ' ' << j << endl;
        iv.push_back({i, j});
      }
    }
  }
  // who if0 if1
  int pnt = (int)iv.size();
  vector<int> v_row(n, -1);
  vector<int> v_col(n, -1);
  for (int i = 0; i < n; i++) {
    if (need_row[i] != -1) {
      cerr << "R: " << i << ' ' << need_row[i] << '\n';
      v_row[i] = pnt;
      pnt++;
    }
  }
  for (int j = 0; j < n; j++) {
    if (need_col[j] != -1) {
      cerr << "C: " << j << ' ' << need_col[j] << '\n';
      v_col[j] = pnt;
      pnt++;
    }
  }
  int st = pnt;
  int en = pnt + 1;
  MaxFlow::init(pnt + 2, st, en);
  cerr << "INIT OK" << endl;
  vector<int> ed_i(iv.size(), -1);
  vector<int> ed_r(iv.size(), -1);
  vector<int> ed_c(iv.size(), -1);
  for (int i = 0; i < (int)iv.size(); i++) {
    cerr << "+" << endl;
    ed_i[i] = MaxFlow::add_edge(st, i, 1);
    int ri, rj;
    tie(ri, rj) = iv[i];
    cerr << ri << ' ' << rj << endl;
    if (v_row[ri] != -1)
      assert(need_row[ri] != need_col[rj]);
    if (v_row[ri] != -1) {
      ed_r[i] = MaxFlow::add_edge(i, v_row[ri], 1);
    }
    if (v_col[rj] != -1) {
      ed_c[i] = MaxFlow::add_edge(i, v_col[rj], 1);
    }
    cerr << "~" << endl;
  }
  int c = 0;
  for (int i = 0; i < n; i++) {
    if (v_row[i] != -1) {
      MaxFlow::add_edge(v_row[i], en, 1);
      c++;
    }
  }
  for (int j = 0; j < n; j++) {
    if (v_col[j] != -1) {
      MaxFlow::add_edge(v_col[j], en, 1);
      c++;
    }
  }
  cerr << "STARTING FLOW " << c << endl;
  int fl = MaxFlow::solve();
  cerr << "FLOW OK" << endl;
  if (c != fl) {
    return 0;
  }
  for (int i = 0; i < (int)iv.size(); i++) {
    int ri, rj;
    tie(ri, rj) = iv[i];
    if (ed_r[i] != -1 && MaxFlow::ed[ed_r[i]].flow) {
      tans[ri][rj] = need_row[ri];
    } else if (ed_c[i] != -1 && MaxFlow::ed[ed_c[i]].flow) {
      tans[ri][rj] = need_col[rj];
    } else {
      assert(MaxFlow::ed[ed_i[i]].flow == 0);
      tans[ri][rj] = 0;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      assert(tans[i][j] == 0 || tans[i][j] == 1);
    }
  }
  return 1;
}

typedef unsigned long long ull;

const int K = 64;

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;
  vector<vector<ull>> ans(n, vector<ull>(n));
  vector<ull> u(n);
  vector<ull> v(n);
  for (int i = 0; i < n; i++) {
    cin >> s[i];
  }
  for (int i = 0; i < n; i++) {
    cin >> t[i];
  }
  for (auto &x : u) {
    cin >> x;
  }
  for (auto &x : v) {
    cin >> x;
  }
  int ok = 1;
  for (int i = 0; i < K; i++) {
    vector<int> nu(n);
    vector<int> nv(n);
    for (int j = 0; j < n; j++) {
      ub[j] = ((u[j] >> i) & 1);
      vb[j] = ((v[j] >> i) & 1);
    }
    if (!solve_bit(n)) {
      ok = 0;
    }
    for (int ff = 0; ff < n; ff++) {
      for (int ss = 0; ss < n; ss++) {
        if (tans[ff][ss] == 1) {
          ans[ff][ss] |= (1LL << i);
        }
      }
    }
  }
  if (!ok) {
    cout << -1 << endl;
    return 0;
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      cout << ans[i][j] << ' ';
    }
    cout << '\n';
  }
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

#define cerr                                                                   \
  if (false)                                                                   \
  cerr

struct Edge {
  int u, v;
  int cap, flow;

  Edge(int u_, int v_, int cap_, int flow_)
      : u(u_), v(v_), cap(cap_), flow(flow_) {}
};

const int N = 502;
const int LIM = N * N;

namespace MaxFlow {
const int INF = 1e9 + 239;
const int MAX_LOG = 1;

int n;
int start;
int end;

int d[LIM];
int pnt[LIM];
vector<int> g[LIM];

vector<Edge> ed;

int dfs(int u, int flow) {
  if (flow == 0) {
    return 0;
  }
  if (u == end) {
    return flow;
  }
  for (; pnt[u] < (int)g[u].size(); pnt[u]++) {
    int ind = g[u][pnt[u]];
    int to = ed[ind].v;
    if (d[to] < d[u] + 1) {
      continue;
    }
    int pushed = dfs(to, min(flow, ed[ind].cap - ed[ind].flow));
    if (pushed > 0) {
      ed[ind].flow += pushed;
      ed[ind ^ 1].flow -= pushed;
      return pushed;
    }
  }
  return 0;
}

bool bfs(int lim) {
  for (int i = 0; i < n; i++) {
    d[i] = INF;
  }
  d[start] = 0;
  queue<int> q;
  q.push(start);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (auto ind : g[u]) {
      int to = ed[ind].v;
      if (d[to] > d[u] + 1 && ed[ind].flow + lim <= ed[ind].cap) {
        d[to] = d[u] + 1;
        q.push(to);
      }
    }
  }
  return d[end] < INF;
}

void init(int n_, int start_, int end_) {
  n = n_;
  start = start_;
  end = end_;
  ed.clear();
  fill(d, d + n, 0);
  fill(pnt, pnt + n, 0);
  for (int i = 0; i < n; i++) {
    g[i].clear();
  }
}

int add_edge(int u, int v, int c) {
  assert(u < n);
  assert(v < n);
  int pnt_ed = (int)ed.size();
  ed.push_back(Edge(u, v, c, 0));
  ed.push_back(Edge(v, u, 0, 0));
  g[u].push_back(pnt_ed);
  g[v].push_back(pnt_ed + 1);
  return pnt_ed;
}

int solve() {
  int ans = 0;
  for (int i = MAX_LOG; i >= 0; i--) {
    while (bfs(1LL << i)) {
      fill(pnt, pnt + n, 0);
      while (true) {
        int nw = dfs(start, INF);
        if (nw > 0) {
          ans += nw;
        } else {
          break;
        }
      }
    }
  }
  return ans;
}
}; // namespace MaxFlow

int s[N];
int t[N];
int ub[N];
int vb[N];
int tans[N][N];

int solve_bit(int n) {
  int all_ok = 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      tans[i][j] = -1;
    }
  }
  auto safe_set = [&](int i, int j, int val) {
    if (tans[i][j] != -1 && tans[i][j] != val) {
      all_ok = 0;
    }
    tans[i][j] = val;
  };
  vector<int> need_row(n, -1);
  vector<int> need_col(n, -1);
  for (int i = 0; i < n; i++) {
    if (s[i] == 0 && ub[i] == 1) {
      // cerr << "R " << i << ' ' << 0 << endl;
      for (int j = 0; j < n; j++) {
        safe_set(i, j, 1);
      }
    } else if (s[i] == 1 && ub[i] == 0) {
      // cerr << "R " << i << ' ' << 1 << endl;
      for (int j = 0; j < n; j++) {
        safe_set(i, j, 0);
      }
    } else {
      if (s[i] == 0) {
        need_row[i] = 0;
      } else {
        need_row[i] = 1;
      }
    }
  }
  for (int j = 0; j < n; j++) {
    if (t[j] == 0 && vb[j] == 1) {
      for (int i = 0; i < n; i++) {
        safe_set(i, j, 1);
      }
    } else if (t[j] == 1 && vb[j] == 0) {
      for (int i = 0; i < n; i++) {
        safe_set(i, j, 0);
      }
    } else {
      if (t[j] == 0) {
        need_col[j] = 0;
      } else {
        need_col[j] = 1;
      }
    }
  }

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (tans[i][j] == -1 && need_row[i] != -1 && need_row[i] == need_col[j]) {
        cerr << "ADD " << i << ' ' << j << endl;
        safe_set(i, j, need_row[i]);
      }
      if (tans[i][j] != -1) {
        if (tans[i][j] == need_row[i]) {
          need_row[i] = -1;
        }
        if (tans[i][j] == need_col[j]) {
          need_col[j] = -1;
        }
      }
    }
  }
  {
    cerr << "need_row: " << endl;
    for (auto x : need_row) {
      cerr << x << ' ';
    }
    cerr << endl;
  }

  {
    cerr << "need_col: " << endl;
    for (auto x : need_col) {
      cerr << x << ' ';
    }
    cerr << endl;
  }
  if (!all_ok) {
    return 0;
  }
  cerr << "HR " << endl;
  vector<pair<int, int>> iv;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (tans[i][j] == -1) {
        cerr << "EMP " << i << ' ' << j << endl;
        iv.push_back({i, j});
      }
    }
  }
  // who if0 if1
  int pnt = (int)iv.size();
  vector<int> v_row(n, -1);
  vector<int> v_col(n, -1);
  for (int i = 0; i < n; i++) {
    if (need_row[i] != -1) {
      cerr << "R: " << i << ' ' << need_row[i] << '\n';
      v_row[i] = pnt;
      pnt++;
    }
  }
  for (int j = 0; j < n; j++) {
    if (need_col[j] != -1) {
      cerr << "C: " << j << ' ' << need_col[j] << '\n';
      v_col[j] = pnt;
      pnt++;
    }
  }
  int st = pnt;
  int en = pnt + 1;
  MaxFlow::init(pnt + 2, st, en);
  cerr << "INIT OK" << endl;
  vector<int> ed_i(iv.size(), -1);
  vector<int> ed_r(iv.size(), -1);
  vector<int> ed_c(iv.size(), -1);
  for (int i = 0; i < (int)iv.size(); i++) {
    cerr << "+" << endl;
    ed_i[i] = MaxFlow::add_edge(st, i, 1);
    int ri, rj;
    tie(ri, rj) = iv[i];
    cerr << ri << ' ' << rj << endl;
    if (v_row[ri] != -1)
      assert(need_row[ri] != need_col[rj]);
    if (v_row[ri] != -1) {
      ed_r[i] = MaxFlow::add_edge(i, v_row[ri], 1);
    }
    if (v_col[rj] != -1) {
      ed_c[i] = MaxFlow::add_edge(i, v_col[rj], 1);
    }
    cerr << "~" << endl;
  }
  int c = 0;
  for (int i = 0; i < n; i++) {
    if (v_row[i] != -1) {
      MaxFlow::add_edge(v_row[i], en, 1);
      c++;
    }
  }
  for (int j = 0; j < n; j++) {
    if (v_col[j] != -1) {
      MaxFlow::add_edge(v_col[j], en, 1);
      c++;
    }
  }
  cerr << "STARTING FLOW " << c << endl;
  int fl = MaxFlow::solve();
  cerr << "FLOW OK" << endl;
  if (c != fl) {
    return 0;
  }
  for (int i = 0; i < (int)iv.size(); i++) {
    int ri, rj;
    tie(ri, rj) = iv[i];
    if (ed_r[i] != -1 && MaxFlow::ed[ed_r[i]].flow) {
      tans[ri][rj] = need_row[ri];
    } else if (ed_c[i] != -1 && MaxFlow::ed[ed_c[i]].flow) {
      tans[ri][rj] = need_col[rj];
    } else {
      assert(MaxFlow::ed[ed_i[i]].flow == 0);
      tans[ri][rj] = 0;
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      assert(tans[i][j] == 0 || tans[i][j] == 1);
    }
  }
  return 1;
}

typedef unsigned long long ull;

const int K = 64;

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;
  vector<vector<ull>> ans(n, vector<ull>(n));
  vector<ull> u(n);
  vector<ull> v(n);
  for (int i = 0; i < n; i++) {
    cin >> s[i];
  }
  for (int i = 0; i < n; i++) {
    cin >> t[i];
  }
  for (auto &x : u) {
    cin >> x;
  }
  for (auto &x : v) {
    cin >> x;
  }
  int ok = 1;
  for (int i = 0; i < K; i++) {
    vector<int> nu(n);
    vector<int> nv(n);
    for (int j = 0; j < n; j++) {
      ub[j] = ((u[j] >> i) & 1);
      vb[j] = ((v[j] >> i) & 1);
    }
    if (!solve_bit(n)) {
      ok = 0;
    }
    for (int ff = 0; ff < n; ff++) {
      for (int ss = 0; ss < n; ss++) {
        if (tans[ff][ss] == 1) {
          ans[ff][ss] |= (1LL << i);
        }
      }
    }
  }
  if (!ok) {
    cout << -1 << endl;
    return 0;
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      cout << ans[i][j] << ' ';
    }
    cout << '\n';
  }
}