Problem p03084 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

struct FastIO {
  FastIO() {
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
} fastio_beet;

// INSERT ABOVE HERE
signed main() {
  int n, m, q;
  cin >> n >> m >> q;
  string s, t;
  cin >> s >> t;

  const int INF = 1e9;
  vector<int> vw, ve, vn, vs;
  vw.emplace_back(-INF);
  ve.emplace_back(-INF);
  vn.emplace_back(-INF);
  vs.emplace_back(-INF);
  for (int i = 0; i < n; i++) {
    if (s[i] == 'W')
      vw.emplace_back(i);
    if (s[i] == 'E')
      ve.emplace_back(i);
  }
  for (int i = 0; i < m; i++) {
    if (t[i] == 'N')
      vn.emplace_back(i);
    if (t[i] == 'S')
      vs.emplace_back(i);
  }
  vw.emplace_back(+INF);
  ve.emplace_back(+INF);
  vn.emplace_back(+INF);
  vs.emplace_back(+INF);

  for (int i = 0; i < q; i++) {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    a--;
    b--;
    c--;
    d--;

    using ll = long long;
    auto T = [&](int y, int x, int step) {
      return ((ll)y << 40) | ((ll)x << 20) | (ll)step;
    };
    unordered_map<ll, int> dp;
    using P = pair<int, ll>;
    priority_queue<P, vector<P>, greater<P>> pq;
    dp[T(a, b, 0)] = 0;
    pq.emplace(dp[T(a, b, 0)], T(a, b, 0));

    int ans = INF;
    while (!pq.empty()) {
      int sum = pq.top().first;
      ll st = pq.top().second;
      pq.pop();
      if (dp[st] < sum)
        continue;
      int y, x, step;
      y = (st >> 40);
      x = (st >> 20) ^ ((ll)y << 20);
      step = st & ((1 << 20) - 1);

      if (sum + abs(y - c) + abs(x - d) >= ans)
        continue;

      if ((s[y] == 'E' && x <= d) || (s[y] == 'W' && x >= d))
        if ((t[d] == 'S' && y <= c) || (t[d] == 'N' && y >= c))
          chmin(ans, sum + abs(y - c) + abs(x - d));

      if ((t[x] == 'S' && y <= c) || (t[x] == 'N' && y >= c))
        if ((s[c] == 'E' && x <= d) || (s[c] == 'W' && x >= d))
          chmin(ans, sum + abs(y - c) + abs(x - d));

      if (sum + abs(y - c) + abs(x - d) >= ans)
        continue;
      if (step >= 3)
        continue;
      auto push = [&](int ny, int nx, int ns, int nd) {
        if (abs(ny) == INF || abs(nx) == INF)
          return;
        if (dp.count(T(ny, nx, ns)) && dp[T(ny, nx, ns)] <= nd)
          return;
        dp[T(ny, nx, ns)] = nd;
        pq.emplace(nd, T(ny, nx, ns));
      };

      if (s[y] == 'W') {
        // N
        for (int xx : {x, d}) {
          auto it = --upper_bound(vn.begin(), vn.end(), xx);
          if (*it <= x)
            push(y, *it, step + 1, sum + abs(*it - x));
        }
        // S
        for (int xx : {x, d}) {
          auto it = --upper_bound(vs.begin(), vs.end(), xx);
          if (*it <= x)
            push(y, *it, step + 1, sum + abs(*it - x));
        }
      } else {
        // N
        for (int xx : {x, d}) {
          auto it = lower_bound(vn.begin(), vn.end(), xx);
          if (x <= *it)
            push(y, *it, step + 1, sum + abs(*it - x));
        }
        // S
        for (int xx : {x, d}) {
          auto it = lower_bound(vs.begin(), vs.end(), xx);
          if (x <= *it)
            push(y, *it, step + 1, sum + abs(*it - x));
        }
      }
      if (t[x] == 'N') {
        // W
        for (int yy : {y, c}) {
          auto it = --upper_bound(vw.begin(), vw.end(), yy);
          if (*it <= y)
            push(*it, x, step + 1, sum + abs(*it - y));
        }
        // E
        for (int yy : {y, c}) {
          auto it = --upper_bound(ve.begin(), ve.end(), yy);
          if (*it <= y)
            push(*it, x, step + 1, sum + abs(*it - y));
        }
      } else {
        // W
        for (int yy : {y, c}) {
          auto it = lower_bound(vw.begin(), vw.end(), yy);
          if (y <= *it)
            push(*it, x, step + 1, sum + abs(*it - y));
        }
        // E
        for (int yy : {y, c}) {
          auto it = lower_bound(ve.begin(), ve.end(), yy);
          if (y <= *it)
            push(*it, x, step + 1, sum + abs(*it - y));
        }
      }
    }
    if (ans == INF)
      ans = -1;
    cout << ans << "\n";
  }
  cout << flush;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using Int = long long;
template <typename T1, typename T2> inline void chmin(T1 &a, T2 b) {
  if (a > b)
    a = b;
}
template <typename T1, typename T2> inline void chmax(T1 &a, T2 b) {
  if (a < b)
    a = b;
}

struct FastIO {
  FastIO() {
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
} fastio_beet;

// INSERT ABOVE HERE
signed main() {
  int n, m, q;
  cin >> n >> m >> q;
  string s, t;
  cin >> s >> t;

  const int INF = 1e9;
  vector<int> vw, ve, vn, vs;
  vw.emplace_back(-INF);
  ve.emplace_back(-INF);
  vn.emplace_back(-INF);
  vs.emplace_back(-INF);
  for (int i = 0; i < n; i++) {
    if (s[i] == 'W')
      vw.emplace_back(i);
    if (s[i] == 'E')
      ve.emplace_back(i);
  }
  for (int i = 0; i < m; i++) {
    if (t[i] == 'N')
      vn.emplace_back(i);
    if (t[i] == 'S')
      vs.emplace_back(i);
  }
  vw.emplace_back(+INF);
  ve.emplace_back(+INF);
  vn.emplace_back(+INF);
  vs.emplace_back(+INF);

  for (int i = 0; i < q; i++) {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    a--;
    b--;
    c--;
    d--;

    using ll = long long;
    auto T = [&](int y, int x, int step) {
      return ((ll)y << 40) | ((ll)x << 20) | (ll)step;
    };
    unordered_map<ll, int> dp;
    using P = pair<int, ll>;
    priority_queue<P, vector<P>, greater<P>> pq;
    dp[T(a, b, 0)] = 0;
    pq.emplace(dp[T(a, b, 0)], T(a, b, 0));

    int ans = INF;
    while (!pq.empty()) {
      int sum = pq.top().first;
      ll st = pq.top().second;
      pq.pop();
      if (dp[st] < sum)
        continue;
      int y, x, step;
      y = (st >> 40);
      x = (st >> 20) ^ ((ll)y << 20);
      step = st & ((1 << 20) - 1);

      if (sum + abs(y - c) + abs(x - d) >= ans)
        continue;

      if ((s[y] == 'E' && x <= d) || (s[y] == 'W' && x >= d))
        if ((t[d] == 'S' && y <= c) || (t[d] == 'N' && y >= c))
          chmin(ans, sum + abs(y - c) + abs(x - d));

      if ((t[x] == 'S' && y <= c) || (t[x] == 'N' && y >= c))
        if ((s[c] == 'E' && x <= d) || (s[c] == 'W' && x >= d))
          chmin(ans, sum + abs(y - c) + abs(x - d));

      if (sum + abs(y - c) + abs(x - d) >= ans)
        continue;
      if (step >= 3)
        continue;
      auto push = [&](int ny, int nx, int ns, int nd) {
        if (abs(ny) == INF || abs(nx) == INF)
          return;
        if (ny == y && nx == x)
          return;
        if (dp.count(T(ny, nx, ns)) && dp[T(ny, nx, ns)] <= nd)
          return;
        dp[T(ny, nx, ns)] = nd;
        pq.emplace(nd, T(ny, nx, ns));
      };

      if (s[y] == 'W') {
        // N
        for (int xx : {x, d}) {
          auto it = --upper_bound(vn.begin(), vn.end(), xx);
          if (*it <= x)
            push(y, *it, step + 1, sum + abs(*it - x));
        }
        // S
        for (int xx : {x, d}) {
          auto it = --upper_bound(vs.begin(), vs.end(), xx);
          if (*it <= x)
            push(y, *it, step + 1, sum + abs(*it - x));
        }
      } else {
        // N
        for (int xx : {x, d}) {
          auto it = lower_bound(vn.begin(), vn.end(), xx);
          if (x <= *it)
            push(y, *it, step + 1, sum + abs(*it - x));
        }
        // S
        for (int xx : {x, d}) {
          auto it = lower_bound(vs.begin(), vs.end(), xx);
          if (x <= *it)
            push(y, *it, step + 1, sum + abs(*it - x));
        }
      }
      if (t[x] == 'N') {
        // W
        for (int yy : {y, c}) {
          auto it = --upper_bound(vw.begin(), vw.end(), yy);
          if (*it <= y)
            push(*it, x, step + 1, sum + abs(*it - y));
        }
        // E
        for (int yy : {y, c}) {
          auto it = --upper_bound(ve.begin(), ve.end(), yy);
          if (*it <= y)
            push(*it, x, step + 1, sum + abs(*it - y));
        }
      } else {
        // W
        for (int yy : {y, c}) {
          auto it = lower_bound(vw.begin(), vw.end(), yy);
          if (y <= *it)
            push(*it, x, step + 1, sum + abs(*it - y));
        }
        // E
        for (int yy : {y, c}) {
          auto it = lower_bound(ve.begin(), ve.end(), yy);
          if (y <= *it)
            push(*it, x, step + 1, sum + abs(*it - y));
        }
      }
    }
    if (ans == INF)
      ans = -1;
    cout << ans << "\n";
  }
  cout << flush;
  return 0;
}