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

#include <bits/stdc++.h>
using namespace std;
/*{{{*/ // template
#define REP(i, n) for (int i = 0; i < n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1 << 29
#define LINF LLONG_MAX / 3
#define MP make_pair
#define PB push_back
#define pb push_back
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define all(v) ALL(v)
#define debug(x) cerr << #x << ":" << x << endl
#define debug2(x, y) cerr << #x << "," << #y ":" << x << "," << y << endl
#define CININIT cin.tie(0), ios::sync_with_stdio(false)
// struct fin{ fin(){ cin.tie(0); ios::sync_with_stdio(false); } } fin_;
struct Double {
  double d;
  explicit Double(double x) : d(x) {}
};
ostream &operator<<(ostream &os, const Double x) {
  os << fixed << setprecision(20) << x.d;
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &st) {
  os << "[";
  for (auto a : st)
    cout << a << ",";
  os << "]";
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}

constexpr ll mod = 1e9 + 7;
constexpr int dx[] = {0, -1, -2, -2, -2, -2, -2, -1, 0, 1, 2, 2, 2, 2, 2, 1};
constexpr int dy[] = {2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1, 0, 1, 2, 2};
/*}}}*/

constexpr int MAX_K = 100010;

int N, M, K;
int X[MAX_K], Y[MAX_K];
// bool used[MAX_K];
unordered_map<int, unordered_map<int, int>> tbl;
unordered_map<int, unordered_map<int, bool>> vis;
set<pii> ex;

// black: ??????????????????
// white: ???????????????

int main() {
  cin >> N >> M >> K;
  rep(i, K) {
    cin >> X[i] >> Y[i];
    tbl[X[i]][Y[i]] = 0;
    vis[X[i]][Y[i]] = false;
    ex.insert(pii(X[i], Y[i]));
  }

  queue<pii> que;
  for (int i = 0; i < K; i++) {
    if (vis[X[i]][Y[i]])
      continue;
    int x = X[i], y = Y[i];
    if (x == 0 or y == M - 1) {
      // debug2(x,y);
      que.push(pii(x, y));
      vis[x][y] = true;
    }
  }

  // cerr << "check1" << endl;
  while (!que.empty()) {
    auto p = que.front();
    que.pop();
    int x = p.first;
    int y = p.second;
    assert(0 <= x and x < N and 0 <= y and y < M);
    tbl[x][y] |= 1;
    for (int dx = -1; dx <= 1; dx++)
      for (int dy = -1; dy <= 1; dy++)
        if (dx != 0 or dy != 0) {
          int nx = x + dx;
          int ny = y + dy;
          if (nx < 0 or nx >= N or ny < 0 or ny >= M)
            continue;
          if (ex.count(pii(nx, ny)) and
              !vis[nx][ny]) { // black is  exist around (x,y)
            if (nx == 0 and ny == 0)
              continue;
            // cerr << "\\t" << nx << " " << ny << endl;
            vis[nx][ny] = true;
            que.push(pii(nx, ny));
          }
        }
  }

  // cerr << "check2" << endl;
  for (int i = 0; i < K; i++) {
    vis[X[i]][Y[i]] = false;
  }

  for (int i = 0; i < K; i++) {
    if (vis[X[i]][Y[i]])
      continue;
    int x = X[i], y = Y[i];
    if (y == 0 or x == N - 1) {
      que.push(pii(x, y));
      vis[x][y] = true;
    }
  }

  while (!que.empty()) {
    auto p = que.front();
    que.pop();
    int x = p.first;
    int y = p.second;
    assert(0 <= x and x < N and 0 <= y and y < M);
    // debug2(x,y);
    tbl[x][y] |= 2;
    for (int dx = -1; dx <= 1; dx++)
      for (int dy = -1; dy <= 1; dy++)
        if (dx != 0 or dy != 0) {
          int nx = x + dx;
          int ny = y + dy;
          // debug2(nx,ny);
          if (nx < 0 or nx >= N or ny < 0 or ny >= M)
            continue;
          // cerr << "\\t" << nx << " " << ny << " " << ex.count(pii(nx,ny)) << "
          // " << vis[nx][ny] << endl; cerr << "\\t(" << nx << "," << ny << ") ->
          // " << ex.count(pii(nx,ny)) << " " <<  vis[nx][ny] << endl;
          if (ex.count(pii(nx, ny)) and
              !vis[nx][ny]) { // black is  exist around (x,y)
            vis[nx][ny] = true;
            que.push(pii(nx, ny));
          }
        }
  }

  // debug
  // for(int i=0;i<N;i++){
  //    for(int j=0;j<M;j++){
  //        cerr << tbl[i][j] << " ";
  //    }
  //    cerr << endl;
  //}

  for (int i = 0; i < K; i++) {
    if (tbl[X[i]][Y[i]] == 3) {
      cout << 0 << endl;
      return 0;
    }
  }

  for (int i = 0; i < K; i++) {
    int x = X[i];
    int y = Y[i];
    if (tbl[x][y] == 1) {
      for (int j = 0; j < 16; j++) {
        int nx = x + dx[j];
        int ny = y + dy[j];
        if (nx >= N or ny < 0) {
          cout << 1 << endl;
          return 0;
        }
        if (nx < 0 or nx >= N or ny < 0 or ny >= M)
          continue;
        if (tbl[nx][ny] == 2) {
          cout << 1 << endl;
          return 0;
        }
      }
    } else if (tbl[x][y] == 2) {
      for (int j = 0; j < 16; j++) {
        int nx = x + dx[j];
        int ny = y + dy[j];
        if (nx < 0 or ny >= M) {
          cout << 1 << endl;
          return 0;
        }
        if (nx < 0 or nx >= N or ny < 0 or ny >= M)
          continue;
        if (tbl[nx][ny] == 1) {
          cout << 1 << endl;
          return 0;
        }
      }
    }
  }

  cout << 2 << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
/*{{{*/ // template
#define REP(i, n) for (int i = 0; i < n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1 << 29
#define LINF LLONG_MAX / 3
#define MP make_pair
#define PB push_back
#define pb push_back
#define EB emplace_back
#define ALL(v) (v).begin(), (v).end()
#define all(v) ALL(v)
#define debug(x) cerr << #x << ":" << x << endl
#define debug2(x, y) cerr << #x << "," << #y ":" << x << "," << y << endl
#define CININIT cin.tie(0), ios::sync_with_stdio(false)
// struct fin{ fin(){ cin.tie(0); ios::sync_with_stdio(false); } } fin_;
struct Double {
  double d;
  explicit Double(double x) : d(x) {}
};
ostream &operator<<(ostream &os, const Double x) {
  os << fixed << setprecision(20) << x.d;
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << "," << p.second << ")";
  return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &st) {
  os << "[";
  for (auto a : st)
    cout << a << ",";
  os << "]";
}
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}

constexpr ll mod = 1e9 + 7;
constexpr int dx[] = {0, -1, -2, -2, -2, -2, -2, -1, 0, 1, 2, 2, 2, 2, 2, 1};
constexpr int dy[] = {2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2, -1, 0, 1, 2, 2};
/*}}}*/

constexpr int MAX_K = 100010;

int N, M, K;
int X[MAX_K], Y[MAX_K];
// bool used[MAX_K];
map<int, map<int, int>> tbl;
map<int, map<int, bool>> vis;
set<pii> ex;

// black: ??????????????????
// white: ???????????????

int main() {
  cin >> N >> M >> K;
  rep(i, K) {
    cin >> X[i] >> Y[i];
    tbl[X[i]][Y[i]] = 0;
    vis[X[i]][Y[i]] = false;
    ex.insert(pii(X[i], Y[i]));
  }

  queue<pii> que;
  for (int i = 0; i < K; i++) {
    if (vis[X[i]][Y[i]])
      continue;
    int x = X[i], y = Y[i];
    if (x == 0 or y == M - 1) {
      // debug2(x,y);
      que.push(pii(x, y));
    }
  }

  // cerr << "check1" << endl;
  while (!que.empty()) {
    auto p = que.front();
    que.pop();
    int x = p.first;
    int y = p.second;
    assert(0 <= x and x < N and 0 <= y and y < M);
    tbl[x][y] |= 1;
    for (int dx = -1; dx <= 1; dx++)
      for (int dy = -1; dy <= 1; dy++)
        if (dx != 0 or dy != 0) {
          int nx = x + dx;
          int ny = y + dy;
          if (nx < 0 or nx >= N or ny < 0 or ny >= M)
            continue;
          if (ex.count(pii(nx, ny)) and
              !vis[nx][ny]) { // black is  exist around (x,y)
            if (nx == 0 and ny == 0)
              continue;
            // cerr << "\\t" << nx << " " << ny << endl;
            vis[x][y] = true;
            que.push(pii(nx, ny));
          }
        }
  }

  // cerr << "check2" << endl;
  for (int i = 0; i < K; i++) {
    vis[X[i]][Y[i]] = false;
  }

  for (int i = 0; i < K; i++) {
    if (vis[X[i]][Y[i]])
      continue;
    int x = X[i], y = Y[i];
    if (y == 0 or x == N - 1) {
      que.push(pii(x, y));
    }
  }

  while (!que.empty()) {
    auto p = que.front();
    que.pop();
    int x = p.first;
    int y = p.second;
    assert(0 <= x and x < N and 0 <= y and y < M);
    // debug2(x,y);
    tbl[x][y] |= 2;
    for (int dx = -1; dx <= 1; dx++)
      for (int dy = -1; dy <= 1; dy++)
        if (dx != 0 or dy != 0) {
          int nx = x + dx;
          int ny = y + dy;
          // debug2(nx,ny);
          if (nx < 0 or nx >= N or ny < 0 or ny >= M)
            continue;
          // cerr << "\\t" << nx << " " << ny << " " << ex.count(pii(nx,ny)) << "
          // " << vis[nx][ny] << endl; cerr << "\\t(" << nx << "," << ny << ") ->
          // " << ex.count(pii(nx,ny)) << " " <<  vis[nx][ny] << endl;
          if (ex.count(pii(nx, ny)) and
              !vis[nx][ny]) { // black is  exist around (x,y)
            vis[x][y] = true;
            que.push(pii(nx, ny));
          }
        }
  }

  // debug
  // for(int i=0;i<N;i++){
  //    for(int j=0;j<M;j++){
  //        cerr << tbl[i][j] << " ";
  //    }
  //    cerr << endl;
  //}

  for (int i = 0; i < K; i++) {
    if (tbl[X[i]][Y[i]] == 3) {
      cout << 0 << endl;
      return 0;
    }
  }

  for (int i = 0; i < K; i++) {
    int x = X[i];
    int y = Y[i];
    if (tbl[x][y] == 1) {
      for (int j = 0; j < 16; j++) {
        int nx = x + dx[j];
        int ny = y + dy[j];
        if (nx >= N or ny < 0) {
          cout << 1 << endl;
          return 0;
        }
        if (nx < 0 or nx >= N or ny < 0 or ny >= M)
          continue;
        if (tbl[nx][ny] == 2) {
          cout << 1 << endl;
          return 0;
        }
      }
    } else if (tbl[x][y] == 2) {
      for (int j = 0; j < 16; j++) {
        int nx = x + dx[j];
        int ny = y + dy[j];
        if (nx < 0 or ny >= M) {
          cout << 1 << endl;
          return 0;
        }
        if (nx < 0 or nx >= N or ny < 0 or ny >= M)
          continue;
        if (tbl[nx][ny] == 1) {
          cout << 1 << endl;
          return 0;
        }
      }
    }
  }

  cout << 2 << endl;
  return 0;
}