Problem p03084 (C++)

Buggy submission (status: Time Limit Exceeded):
// vvvvvvvvvvvv TEMPLATE vvvvvvvvvvvv
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll linf = 1e18;
const double eps = 1e-12, pi = acos(-1);
#define FOR(i, a, b) for (ll i = (a), __last_##i = (b); i < __last_##i; i++)
#define RFOR(i, a, b) for (ll i = (b)-1, __last_##i = (a); i >= __last_##i; i--)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)
#define __GET_MACRO3(_1, _2, _3, NAME, ...) NAME
#define each(i, a) for (auto &&i : a)
#define rep(...) __GET_MACRO3(__VA_ARGS__, FOR, REP)(__VA_ARGS__)
#define rrep(...) __GET_MACRO3(__VA_ARGS__, RFOR, RREP)(__VA_ARGS__)
#define pb push_back
#define eb emplace_back
#define all(a) begin(a), end(a)
#define chmin(x, v) x = min(x, v)
#define chmax(x, v) x = max(x, v)
template <typename T> ll min(ll a, const T &&b) { return a < b ? a : b; }
template <typename T> ll min(const T &&a, ll b) { return a < b ? a : b; }
template <typename T> ll max(ll a, const T &&b) { return a > b ? a : b; }
template <typename T> ll max(const T &&a, ll b) { return a > b ? a : b; }
template <typename Head> void out(Head h) { cout << h << endl; }
template <typename Head, typename... Tail> void out(Head h, Tail... t) {
  cout << h << " ";
  out(t...);
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  each(x, v) is >> x;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  rep(i, v.size()) {
    if (i)
      os << " ";
    os << v[i];
  }
  return os;
}
ostream &operator<<(ostream &os, const vector<string> &v) {
  rep(i, v.size()) {
    if (i)
      os << endl;
    os << v[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &v) {
  rep(i, v.size()) {
    if (i)
      os << endl;
    os << v[i];
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
struct yes_no : std::numpunct<char> {
  string_type do_truename() const { return "Yes"; }
  string_type do_falsename() const { return "No"; }
};
void solve();
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  locale loc(locale(), new yes_no);
  cout.imbue(loc);
  cout << fixed << setprecision(10) << boolalpha;
  solve();
}
// ^^^^^^^^^^^^ TEMPLATE ^^^^^^^^^^^^

vector<ll> merge(const vector<ll> &a, const vector<ll> &b) {
  vector<ll> res;
  each(x, a) res.pb(x);
  each(x, b) res.pb(x);
  sort(all(res));
  return res;
}

pair<vector<ll>, vector<ll>> merge(const pair<vector<ll>, vector<ll>> &a,
                                   const pair<vector<ll>, vector<ll>> &b) {
  return make_pair(merge(a.first, b.first), merge(a.second, b.second));
}

#define NODE(x, y) ((y)*m + (x))

vector<ll> dijkstra(const vector<vector<P>> &G, const ll s) {
  const ll n = G.size();
  vector<ll> res(n, linf);
  res[s] = 0;
  priority_queue<P, vector<P>, greater<P>> Q;
  Q.push(P(0, s));
  while (!Q.empty()) {
    P p = Q.top();
    Q.pop();
    ll v = p.second;
    if (p.first > res[v])
      continue;
    each(e, G[v]) {
      ll to = e.first, cost = e.second;
      if (res[v] + cost < res[to]) {
        res[to] = res[v] + cost;
        Q.push(P(res[to], to));
      }
    }
  }
  return res;
}

ll solve(const vector<ll> &L, const vector<ll> &R, const vector<ll> &U,
         const vector<ll> &D, ll x1, ll y1, ll x2, ll y2) {
  vector<ll> X = merge(U, D);
  vector<ll> Y = merge(L, R);
  const ll n = Y.size(), m = X.size();
  vector<vector<P>> G(n * m);
  each(yy, L) {
    ll y = lower_bound(all(Y), yy) - Y.begin();
    rep(x, 1, m) { G[NODE(x, y)].eb(NODE(x - 1, y), X[x] - X[x - 1]); }
  }
  each(yy, R) {
    ll y = lower_bound(all(Y), yy) - Y.begin();
    rep(x, 1, m) { G[NODE(x - 1, y)].eb(NODE(x, y), X[x] - X[x - 1]); }
  }
  each(xx, U) {
    ll x = lower_bound(all(X), xx) - X.begin();
    rep(y, 1, n) { G[NODE(x, y)].eb(NODE(x, y - 1), Y[y] - Y[y - 1]); }
  }
  each(xx, D) {
    ll x = lower_bound(all(X), xx) - X.begin();
    rep(y, 1, n) { G[NODE(x, y - 1)].eb(NODE(x, y), Y[y] - Y[y - 1]); }
  }
  x1 = lower_bound(all(X), x1) - X.begin();
  y1 = lower_bound(all(Y), y1) - Y.begin();
  x2 = lower_bound(all(X), x2) - X.begin();
  y2 = lower_bound(all(Y), y2) - Y.begin();
  ll s = NODE(x1, y1), t = NODE(x2, y2);
  vector<ll> dist = dijkstra(G, s);
  return dist[t];
}

void solve() {
  ll h, w, Q;
  cin >> h >> w >> Q;
  string S, T;
  cin >> S >> T;
  vector<ll> U, D, L, R;
  rep(i, h) {
    if (S[i] == 'E') {
      R.pb(i);
    } else {
      L.pb(i);
    }
  }
  rep(i, w) {
    if (T[i] == 'N') {
      U.pb(i);
    } else {
      D.pb(i);
    }
  }
  auto pickup2 = [&](ll x, const vector<ll> &a) {
    auto it = upper_bound(all(a), x);
    vector<ll> res;
    if (it != a.end())
      res.pb(*it);
    if (it != a.begin()) {
      --it;
      res.pb(*it);
      if (*it == x && it != a.begin()) {
        res.pb(*it);
      }
    }
    return res;
  };
  auto pickup = [&](ll x, const vector<ll> &a, const vector<ll> &b) {
    return make_pair(pickup2(x, a), pickup2(x, b));
  };
  rep(q, Q) {
    ll y1, x1, y2, x2;
    cin >> y1 >> x1 >> y2 >> x2;
    --y1, --x1, --y2, --x2;
    auto v1 = pickup(y1, L, R);
    auto v2 = pickup(x1, U, D);
    auto v3 = pickup(y2, L, R);
    auto v4 = pickup(x2, U, D);
    auto a = merge(v1, v3);
    auto b = merge(v2, v4);
    ll ans = solve(a.first, a.second, b.first, b.second, x1, y1, x2, y2);
    if (ans == linf)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
}


Fixed submission:
// vvvvvvvvvvvv TEMPLATE vvvvvvvvvvvv
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
const ll linf = 1e18;
const double eps = 1e-12, pi = acos(-1);
#define FOR(i, a, b) for (ll i = (a), __last_##i = (b); i < __last_##i; i++)
#define RFOR(i, a, b) for (ll i = (b)-1, __last_##i = (a); i >= __last_##i; i--)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)
#define __GET_MACRO3(_1, _2, _3, NAME, ...) NAME
#define each(i, a) for (auto &&i : a)
#define rep(...) __GET_MACRO3(__VA_ARGS__, FOR, REP)(__VA_ARGS__)
#define rrep(...) __GET_MACRO3(__VA_ARGS__, RFOR, RREP)(__VA_ARGS__)
#define pb push_back
#define eb emplace_back
#define all(a) begin(a), end(a)
#define chmin(x, v) x = min(x, v)
#define chmax(x, v) x = max(x, v)
template <typename T> ll min(ll a, const T &&b) { return a < b ? a : b; }
template <typename T> ll min(const T &&a, ll b) { return a < b ? a : b; }
template <typename T> ll max(ll a, const T &&b) { return a > b ? a : b; }
template <typename T> ll max(const T &&a, ll b) { return a > b ? a : b; }
template <typename Head> void out(Head h) { cout << h << endl; }
template <typename Head, typename... Tail> void out(Head h, Tail... t) {
  cout << h << " ";
  out(t...);
}
template <typename T> istream &operator>>(istream &is, vector<T> &v) {
  each(x, v) is >> x;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &v) {
  rep(i, v.size()) {
    if (i)
      os << " ";
    os << v[i];
  }
  return os;
}
ostream &operator<<(ostream &os, const vector<string> &v) {
  rep(i, v.size()) {
    if (i)
      os << endl;
    os << v[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &v) {
  rep(i, v.size()) {
    if (i)
      os << endl;
    os << v[i];
  }
  return os;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << "(" << p.first << ", " << p.second << ")";
}
struct yes_no : std::numpunct<char> {
  string_type do_truename() const { return "Yes"; }
  string_type do_falsename() const { return "No"; }
};
void solve();
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  locale loc(locale(), new yes_no);
  cout.imbue(loc);
  cout << fixed << setprecision(10) << boolalpha;
  solve();
}
// ^^^^^^^^^^^^ TEMPLATE ^^^^^^^^^^^^

vector<ll> merge(const vector<ll> &a, const vector<ll> &b) {
  vector<ll> res;
  each(x, a) res.pb(x);
  each(x, b) res.pb(x);
  sort(all(res));
  res.erase(unique(all(res)), res.end());
  return res;
}

pair<vector<ll>, vector<ll>> merge(const pair<vector<ll>, vector<ll>> &a,
                                   const pair<vector<ll>, vector<ll>> &b) {
  return make_pair(merge(a.first, b.first), merge(a.second, b.second));
}

#define NODE(x, y) ((y)*m + (x))

vector<ll> dijkstra(const vector<vector<P>> &G, const ll s) {
  const ll n = G.size();
  vector<ll> res(n, linf);
  res[s] = 0;
  priority_queue<P, vector<P>, greater<P>> Q;
  Q.push(P(0, s));
  while (!Q.empty()) {
    P p = Q.top();
    Q.pop();
    ll v = p.second;
    if (p.first > res[v])
      continue;
    each(e, G[v]) {
      ll to = e.first, cost = e.second;
      if (res[v] + cost < res[to]) {
        res[to] = res[v] + cost;
        Q.push(P(res[to], to));
      }
    }
  }
  return res;
}

ll solve(const vector<ll> &L, const vector<ll> &R, const vector<ll> &U,
         const vector<ll> &D, ll x1, ll y1, ll x2, ll y2) {
  vector<ll> X = merge(U, D);
  vector<ll> Y = merge(L, R);
  const ll n = Y.size(), m = X.size();
  vector<vector<P>> G(n * m);
  each(yy, L) {
    ll y = lower_bound(all(Y), yy) - Y.begin();
    rep(x, 1, m) { G[NODE(x, y)].eb(NODE(x - 1, y), X[x] - X[x - 1]); }
  }
  each(yy, R) {
    ll y = lower_bound(all(Y), yy) - Y.begin();
    rep(x, 1, m) { G[NODE(x - 1, y)].eb(NODE(x, y), X[x] - X[x - 1]); }
  }
  each(xx, U) {
    ll x = lower_bound(all(X), xx) - X.begin();
    rep(y, 1, n) { G[NODE(x, y)].eb(NODE(x, y - 1), Y[y] - Y[y - 1]); }
  }
  each(xx, D) {
    ll x = lower_bound(all(X), xx) - X.begin();
    rep(y, 1, n) { G[NODE(x, y - 1)].eb(NODE(x, y), Y[y] - Y[y - 1]); }
  }
  x1 = lower_bound(all(X), x1) - X.begin();
  y1 = lower_bound(all(Y), y1) - Y.begin();
  x2 = lower_bound(all(X), x2) - X.begin();
  y2 = lower_bound(all(Y), y2) - Y.begin();
  ll s = NODE(x1, y1), t = NODE(x2, y2);
  vector<ll> dist = dijkstra(G, s);
  return dist[t];
}

void solve() {
  ll h, w, Q;
  cin >> h >> w >> Q;
  string S, T;
  cin >> S >> T;
  vector<ll> U, D, L, R;
  rep(i, h) {
    if (S[i] == 'E') {
      R.pb(i);
    } else {
      L.pb(i);
    }
  }
  rep(i, w) {
    if (T[i] == 'N') {
      U.pb(i);
    } else {
      D.pb(i);
    }
  }
  auto pickup2 = [&](ll x, const vector<ll> &a) {
    auto it = upper_bound(all(a), x);
    vector<ll> res;
    if (it != a.end())
      res.pb(*it);
    if (it != a.begin()) {
      --it;
      res.pb(*it);
      if (*it == x && it != a.begin()) {
        res.pb(*it);
      }
    }
    return res;
  };
  auto pickup = [&](ll x, const vector<ll> &a, const vector<ll> &b) {
    return make_pair(pickup2(x, a), pickup2(x, b));
  };
  rep(q, Q) {
    ll y1, x1, y2, x2;
    cin >> y1 >> x1 >> y2 >> x2;
    --y1, --x1, --y2, --x2;
    auto v1 = pickup(y1, L, R);
    auto v2 = pickup(x1, U, D);
    auto v3 = pickup(y2, L, R);
    auto v4 = pickup(x2, U, D);
    auto a = merge(v1, v3);
    auto b = merge(v2, v4);
    ll ans = solve(a.first, a.second, b.first, b.second, x1, y1, x2, y2);
    if (ans == linf)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
}