Problem p01358 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int n, u, v, m;
int card[100000];
int row[2][1000010], col[2][1000010];
int board[2][500][500];
int rem[2];
int row_n[2][500], col_n[2][500], crs_n[2][2];

void solve() {
  for (int loop = 0; loop < m; loop++) {
    int c = card[loop];

    for (int i = 0; i < 2; i++) {
      if (row[i][c] == -1)
        continue;
      row_n[i][row[i][c]]--;
      if (row_n[i][row[i][c]] == 0)
        rem[i]--;
      col_n[i][col[i][c]]--;
      if (col_n[i][col[i][c]] == 0)
        rem[i]--;
      if (row[i][c] == col[i][c]) {
        crs_n[i][0]--;
        if (crs_n[i][0] == 0)
          rem[i]--;
      }
      if (row[i][c] == n - 1 - col[i][c]) {
        crs_n[i][1]--;
        if (crs_n[i][1] == 0)
          rem[i]--;
      }
    }

    if (rem[0] <= 0 && rem[1] > 0) {
      cout << "USAGI" << endl;
      return;
    }
    if (rem[0] > 0 && rem[1] <= 0) {
      cout << "NEKO" << endl;
      return;
    }
    if (rem[0] <= 0 && rem[1] <= 0) {
      cout << "DRAW" << endl;
      return;
    }
  }
  cout << "DRAW" << endl;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> n >> rem[0] >> rem[1] >> m;

  fill((int *)begin(row), (int *)end(row), -1);
  fill((int *)begin(col), (int *)end(col), -1);

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        cin >> board[i][j][k];
        row[i][board[i][j][k]] = j;
        col[i][board[i][j][k]] = k;
      }
    }
  }

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < n; j++) {
      row_n[i][j] = n;
      if (n != 1)
        col_n[i][j] = n;
    }
    for (int j = 0; j < 2; j++) {
      if (n != 1)
        crs_n[i][j] = n;
    }
  }

  for (int i = 0; i < m; i++) {
    cin >> card[i];
  }

  solve();
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>
using namespace std;

int n, u, v, m;
int card[100000];
int board[2][500][500];
int rem[2];
unordered_set<int> row[2][500], col[2][500], cross[2][2];

void solve() {
  for (int loop = 0; loop < m; loop++) {
    int c = card[loop];

    for (int i = 0; i < 2; i++) {
      for (int j = 0; j < n; j++) {
        if (row[i][j].count(c)) {
          row[i][j].erase(c);
          if (row[i][j].empty())
            rem[i]--;
        }
        if (col[i][j].count(c)) {
          col[i][j].erase(c);
          if (col[i][j].empty())
            rem[i]--;
        }
      }
      for (int j = 0; j < 2; j++) {
        if (cross[i][j].count(c)) {
          cross[i][j].erase(c);
          if (cross[i][j].empty())
            rem[i]--;
        }
      }
    }

    if (rem[0] <= 0 && rem[1] > 0) {
      cout << "USAGI" << endl;
      return;
    }
    if (rem[0] > 0 && rem[1] <= 0) {
      cout << "NEKO" << endl;
      return;
    }
    if (rem[0] <= 0 && rem[1] <= 0) {
      cout << "DRAW" << endl;
      return;
    }
  }
  cout << "DRAW" << endl;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin >> n >> rem[0] >> rem[1] >> m;

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        cin >> board[i][j][k];
      }
    }
  }

  for (int i = 0; i < m; i++) {
    cin >> card[i];
  }

  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        row[i][j].insert(board[i][j][k]);
        if (n != 1) {
          col[i][j].insert(board[i][k][j]);
        }
      }
      if (n != 1) {
        cross[i][0].insert(board[i][j][j]);
        cross[i][1].insert(board[i][j][n - 1 - j]);
      }
    }
  }

  solve();
}