結果

問題 No.2786 RMQ on Grid Path
ユーザー OTTFFOTTFF
提出日時 2024-06-15 10:04:01
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 1,115 ms / 6,000 ms
コード長 5,069 bytes
コンパイル時間 2,896 ms
コンパイル使用メモリ 226,920 KB
実行使用メモリ 93,704 KB
最終ジャッジ日時 2024-06-15 10:04:26
合計ジャッジ時間 23,874 ms
ジャッジサーバーID
(参考情報)
judge2 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,812 KB
testcase_01 AC 2 ms
6,940 KB
testcase_02 AC 3 ms
6,944 KB
testcase_03 AC 2 ms
6,944 KB
testcase_04 AC 3 ms
6,944 KB
testcase_05 AC 2 ms
6,940 KB
testcase_06 AC 2 ms
6,940 KB
testcase_07 AC 3 ms
6,944 KB
testcase_08 AC 2 ms
6,940 KB
testcase_09 AC 2 ms
6,940 KB
testcase_10 AC 3 ms
6,940 KB
testcase_11 AC 2 ms
6,940 KB
testcase_12 AC 1,018 ms
85,372 KB
testcase_13 AC 1,001 ms
84,480 KB
testcase_14 AC 1,007 ms
85,684 KB
testcase_15 AC 1,115 ms
85,376 KB
testcase_16 AC 999 ms
85,452 KB
testcase_17 AC 979 ms
85,924 KB
testcase_18 AC 985 ms
84,496 KB
testcase_19 AC 994 ms
85,448 KB
testcase_20 AC 988 ms
84,000 KB
testcase_21 AC 1,016 ms
84,960 KB
testcase_22 AC 690 ms
77,900 KB
testcase_23 AC 709 ms
79,160 KB
testcase_24 AC 714 ms
93,696 KB
testcase_25 AC 664 ms
89,744 KB
testcase_26 AC 696 ms
93,704 KB
testcase_27 AC 222 ms
25,252 KB
testcase_28 AC 138 ms
17,548 KB
testcase_29 AC 828 ms
76,328 KB
testcase_30 AC 154 ms
17,956 KB
testcase_31 AC 28 ms
7,040 KB
testcase_32 AC 549 ms
88,096 KB
testcase_33 AC 68 ms
8,448 KB
testcase_34 AC 454 ms
59,180 KB
testcase_35 AC 455 ms
59,040 KB
testcase_36 AC 453 ms
59,204 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;

int io_=[](){ ios::sync_with_stdio(false); cin.tie(nullptr); return 0; }();

using LL = long long;
using ULL = unsigned long long;
using LD = long double;
using PII = pair<int, int>;
using VI = vector<int>;
using MII = map<int, int>;

template<typename T> void cmin(T &x,const T &y) { if(y<x) x=y; }
template<typename T> void cmax(T &x,const T &y) { if(x<y) x=y; }
template<typename T> bool ckmin(T &x,const T &y) { 
    return y<x ? (x=y, true) : false; }
template<typename T> bool ckmax(T &x,const T &y) { 
    return x<y ? (x=y, true) : false; }
template<typename T> void cmin(T &x,T &y,const T &z) {// x<=y<=z 
    if(z<x) { y=x; x=z; } else if(z<y) y=z; }
template<typename T> void cmax(T &x,T &y,const T &z) {// x>=y>=z
    if(x<z) { y=x; x=z; } else if(y<z) y=z; }

// mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
// mt19937_64 rnd_64(chrono::system_clock::now().time_since_epoch().count());
struct UF {
  int n;
  vector<int> fa;
  UF(int n_=0):n(n_),fa(n_) { 
    for(int i=0;i<n;i++) fa[i]=i;
  }
  void init(int n_) {
    n=n_; fa.assign(n,0);
    for(int i=0;i<n;i++) fa[i]=i;
  }
  int find(int x) { return x==fa[x] ? x : fa[x]=find(fa[x]); }
  bool same(int x,int y) { return find(x)==find(y); }
  bool merge(int x,int y) {
    x=find(x); y=find(y);
    if(x==y) return false;
    fa[x]=y;
    return true;
  }
  vector<vector<int>> getgrps() {
    vector<int> id(n, -1);
    vector<vector<int> > grps;
    for (int i = 0; i < n; i++) {
      if (id[find(i)] == -1) {
        id[find(i)] = grps.size();
        grps.emplace_back();
      }
      grps[id[find(i)]].push_back(i);
    }
    return grps;
  }
};
template<typename Func> struct YCombinatorResult {
  Func func;
  template<typename T>
  explicit YCombinatorResult(T &&func) : func(std::forward<T>(func)) {}
  template<class ...Args> decltype(auto) operator()(Args &&...args) {
    return func(std::ref(*this), std::forward<Args>(args)...);
  }
};
template<typename Func> decltype(auto) y_comb(Func &&fun) {
  return YCombinatorResult<std::decay_t<Func>>(std::forward<Func>(fun));
}
/*
---------1---------2---------3---------4---------5---------6---------7---------
1234567890123456789012345678901234567890123456789012345678901234567890123456789
*/

int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};

void solve() {
  int n, m; cin >> n >> m;
  int nv = n * m;
  vector<vector<int>> a(n, vector<int>(m));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> a[i][j];
    }
  }
  auto getid = [&](int x, int y) -> int {
    return x * m + y;
  };
  // auto getpos = [&](int id) -> PII {
  //   return {id / m, id % m};
  // };

  int q; cin >> q;
  vector<vector<PII>> qs(nv);
  int stx, sty, edx, edy;
  int u, v;
  for (int i = 0; i < q; i++) {
    cin >> stx >> sty >> edx >> edy;
    stx--; sty--; edx--; edy--;
    u = getid(stx, sty); 
    v = getid(edx, edy);

    qs[u].push_back({v, i});
    qs[v].push_back({u, i});
  }

  vector<PII> rk;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      rk.push_back({i, j});
    }
  }
  sort(rk.begin(), rk.end(), [&](const PII& x, const PII& y){
    return a[x.first][x.second] < a[y.first][y.second];
  });
  
  vector<set<int>> ses(nv);
  for (int i = 0; i < nv; i++) {
    ses[i].insert(i);
  }

  vector<int> ans(q);

  auto smart_merge = [&](int u, int v, int nans) {
    // cerr << "merging " << u << ' ' << v << ' ' << nans << endl;

    // merge qs:
    int f = 0;
    // always merge u into v
    if (qs[u].size() > qs[v].size()) {
      f = 1;
      swap(u, v);
    }
    for (auto&& [qv, id] : qs[u]) {
      // cerr << " q " << qv << ' ' << id << endl;
      if (ses[v].count(qv)) {
        // cerr << "addressed!" << endl;
        ans[id] = nans;
      } else {
        qs[v].push_back({qv, id});
      }
    }
    if (f) {
      f = 0;
      swap(qs[u], qs[v]);
      swap(u, v);
    }

    // merge ses:
    if (ses[u].size() > ses[v].size()) {
      f = 1;
      swap(u, v);
    }

    for (int val : ses[u]) {
      // cerr << " v " << val << ' ';
      ses[v].insert(val);
    }
    // cerr << endl;

    if (f) {
      swap(ses[u], ses[v]);
      swap(u, v);
    }

    // cerr << "merged " << u << ' ' << v << endl;
    // for (auto&& [qv, id] : qs[v]) {
    //   cerr << qv << ' ' << id << endl;
    // }
    // cerr << "vals : ";
    // for (int val : ses[v]) {
    //   cerr << val << ' ';
    // }
    // cerr << '\n' << endl;
  };

  vector<vector<int>> vis(n, vector<int>(m));
  UF uf(nv);
  for (auto&& [x, y] : rk) {
    vis[x][y] = 1;
    int id = getid(x, y);
    for (int i = 0; i < 4; i++) {
      int nx = x + dx[i], ny = y + dy[i];

      if (nx < 0 || n <= nx || ny < 0 || m <= ny || !vis[nx][ny]) continue;

      int idv = uf.find(getid(nx, ny));
      if (uf.merge(idv, id)) {
        smart_merge(idv, id, a[x][y]);
      }
    }
  }

  for (int i = 0; i < q; i++) {
    cout << ans[i] << '\n';
  }
}

int main() {
  int t = 1; 
  // cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}
0