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

#include <algorithm>
#include <bitset>
#include <cstdio>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)

typedef long long ll;
unordered_set<int> usetrow[500], usetcol[500], usetdia[2];
unordered_set<int> nsetrow[500], nsetcol[500], nsetdia[2];
unordered_set<int> uuse, nuse;

unordered_map<int, int> ucard2rowindex;
unordered_map<int, int> ucard2colindex;
unordered_map<int, int> ncard2rowindex;
unordered_map<int, int> ncard2colindex;

int main() {

  int N, U, V, M;
  scanf("%d%d%d%d", &N, &U, &V, &M);
  rep(i, N) rep(j, N) {
    int x;
    scanf("%d", &x);
    uuse.insert(x);
    usetrow[i].insert(x);
    ucard2rowindex[x] |= i;
    ucard2colindex[x] |= j;

    usetcol[j].insert(x);
    if (i == j)
      usetdia[0].insert(x);
    if (i == N - 1 - j)
      usetdia[1].insert(x);
  }

  rep(i, N) rep(j, N) {
    int x;
    scanf("%d", &x);
    nuse.insert(x);
    nsetrow[i].insert(x);
    nsetcol[j].insert(x);
    ncard2rowindex[x] = i;
    ncard2colindex[x] = j;

    if (i == j)
      nsetdia[0].insert(x);
    if (i == N - 1 - j)
      nsetdia[1].insert(x);
  }

  if (N == 1) {
    rep(_, M) {
      int x;
      scanf("%d", &x);
      if (uuse.count(x) && nuse.count(x)) {
        if (U == 1 && U == V) {
          puts("DRAW");
        }
        if (U == 1 && U < V) {
          puts("USAGI");
        } else if (V == 1 && V < U) {
          puts("NEKO");
        } else {
          puts("DRAW");
        }
        return 0;
      }
      if (uuse.count(x) && U == 1) {
        puts("USAGI");
        return 0;
      }
      if (nuse.count(x) && V == 1) {
        puts("NEKO");
        return 0;
      }
    }

    puts("DRAW");
    return 0;
  }

  int u = 0, v = 0;
  bool udiaskip = 0;
  bool vdiaskip = 0;

  rep(_, M) {
    int card;
    scanf("%d", &card);
    if (uuse.count(card)) {
      if (!udiaskip) {
        rep(i, 2) {
          if (usetdia[i].count(card)) {
            usetdia[i].erase(card);
            if (usetdia[i].empty()) {
              udiaskip = 1;
              u++;
            }
          }
        }
      }

      {
        auto iter = ucard2rowindex.find(card);
        if (iter != ucard2rowindex.end()) {
          auto idx = iter->second;
          usetrow[idx].erase(card);
          if (usetrow[idx].empty())
            u++;
          ucard2rowindex.erase(card);
        }
      }

      {
        auto iter = ucard2colindex.find(card);
        if (iter != ucard2colindex.end()) {
          auto idx = iter->second;
          usetcol[idx].erase(card);
          if (usetcol[idx].empty())
            u++;
          ucard2colindex.erase(card);
        }
      }
    }

    if (nuse.count(card)) {
      if (!vdiaskip) {
        rep(i, 2) {
          if (nsetdia[i].count(card)) {
            nsetdia[i].erase(card);
            if (nsetdia[i].empty()) {
              v++;
              vdiaskip = 1;
            }
          }
        }
      }

      {
        auto iter = ncard2rowindex.find(card);
        if (iter != ncard2rowindex.end()) {
          auto idx = iter->second;
          nsetrow[idx].erase(card);
          if (nsetrow[idx].empty())
            v++;
          ncard2rowindex.erase(card);
        }
      }

      {
        auto iter = ncard2colindex.find(card);
        if (iter != ncard2colindex.end()) {
          auto idx = iter->second;
          nsetcol[idx].erase(card);
          if (nsetcol[idx].empty())
            v++;
          ncard2colindex.erase(card);
        }
      }
    }

    if (U <= u && V > v) {
      puts("USAGI");
      return 0;
    }
    if (U > u && V <= v) {
      puts("NEKO");
      return 0;
    }

    if (U <= u && V <= v)
      break;
  }

  puts("DRAW");

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

#define REP(i, a, b) for (int i = a; i < (int)b; i++)
#define rep(i, n) REP(i, 0, n)

typedef long long ll;
unordered_set<int> usetrow[500], usetcol[500], usetdia[2];
unordered_set<int> nsetrow[500], nsetcol[500], nsetdia[2];
unordered_set<int> uuse, nuse;

unordered_map<int, vector<int>> ucard2rowindex;
unordered_map<int, vector<int>> ucard2colindex;
unordered_map<int, vector<int>> ncard2rowindex;
unordered_map<int, vector<int>> ncard2colindex;

int main() {

  int N, U, V, M;
  scanf("%d%d%d%d", &N, &U, &V, &M);
  rep(i, N) rep(j, N) {
    int x;
    scanf("%d", &x);
    uuse.insert(x);
    usetrow[i].insert(x);
    ucard2rowindex[x].push_back(i);
    ucard2colindex[x].push_back(j);

    usetcol[j].insert(x);
    if (i == j)
      usetdia[0].insert(x);
    if (i == N - 1 - j)
      usetdia[1].insert(x);
  }

  rep(i, N) rep(j, N) {
    int x;
    scanf("%d", &x);
    nuse.insert(x);
    nsetrow[i].insert(x);
    nsetcol[j].insert(x);
    ncard2rowindex[x].push_back(i);
    ncard2colindex[x].push_back(j);

    if (i == j)
      nsetdia[0].insert(x);
    if (i == N - 1 - j)
      nsetdia[1].insert(x);
  }

  if (N == 1) {
    rep(_, M) {
      int x;
      scanf("%d", &x);
      if (uuse.count(x) && nuse.count(x)) {
        if (U == 1 && U == V) {
          puts("DRAW");
        }
        if (U == 1 && U < V) {
          puts("USAGI");
        } else if (V == 1 && V < U) {
          puts("NEKO");
        } else {
          puts("DRAW");
        }
        return 0;
      }
      if (uuse.count(x) && U == 1) {
        puts("USAGI");
        return 0;
      }
      if (nuse.count(x) && V == 1) {
        puts("NEKO");
        return 0;
      }
    }

    puts("DRAW");
    return 0;
  }

  int u = 0, v = 0;
  bool udiaskip = 0;
  bool vdiaskip = 0;

  rep(_, M) {
    int card;
    scanf("%d", &card);
    if (uuse.count(card)) {
      if (!udiaskip) {
        rep(i, 2) {
          if (usetdia[i].count(card)) {
            usetdia[i].erase(card);
            if (usetdia[i].empty()) {
              udiaskip = 1;
              u++;
            }
          }
        }
      }

      {
        auto iter = ucard2rowindex.find(card);
        if (iter != ucard2rowindex.end()) {
          auto &vec = iter->second;
          rep(i, vec.size()) {
            usetrow[vec[i]].erase(card);
            if (usetrow[vec[i]].empty())
              u++;
          }
          ucard2rowindex.erase(card);
        }
      }

      {
        auto iter = ucard2colindex.find(card);
        if (iter != ucard2colindex.end()) {
          auto &vec = iter->second;
          rep(i, vec.size()) {
            usetcol[vec[i]].erase(card);
            if (usetcol[vec[i]].empty())
              u++;
          }
          ucard2colindex.erase(card);
        }
      }
    }

    if (nuse.count(card)) {
      if (!vdiaskip) {
        rep(i, 2) {
          if (nsetdia[i].count(card)) {
            nsetdia[i].erase(card);
            if (nsetdia[i].empty()) {
              v++;
              vdiaskip = 1;
            }
          }
        }
      }

      {
        auto iter = ncard2rowindex.find(card);
        if (iter != ncard2rowindex.end()) {
          auto &vec = iter->second;
          rep(i, vec.size()) {
            nsetrow[vec[i]].erase(card);
            if (nsetrow[vec[i]].empty())
              v++;
          }
          ncard2rowindex.erase(card);
        }
      }

      {
        auto iter = ncard2colindex.find(card);
        if (iter != ncard2colindex.end()) {
          auto &vec = iter->second;
          rep(i, vec.size()) {
            nsetcol[vec[i]].erase(card);
            if (nsetcol[vec[i]].empty())
              v++;
          }
          ncard2colindex.erase(card);
        }
      }
    }

    if (U <= u && V > v) {
      puts("USAGI");
      return 0;
    }
    if (U > u && V <= v) {
      puts("NEKO");
      return 0;
    }

    if (U <= u && V <= v)
      break;
  }

  puts("DRAW");

  return 0;
}