結果
問題 | No.2786 RMQ on Grid Path |
ユーザー | a1048576 |
提出日時 | 2024-06-14 21:53:15 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 2,926 bytes |
コンパイル時間 | 4,077 ms |
コンパイル使用メモリ | 246,536 KB |
実行使用メモリ | 434,012 KB |
最終ジャッジ日時 | 2024-06-14 21:53:32 |
合計ジャッジ時間 | 12,915 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 4 ms
434,012 KB |
testcase_01 | AC | 6 ms
9,256 KB |
testcase_02 | AC | 13 ms
9,320 KB |
testcase_03 | AC | 14 ms
9,144 KB |
testcase_04 | AC | 14 ms
9,252 KB |
testcase_05 | AC | 12 ms
9,536 KB |
testcase_06 | AC | 12 ms
9,292 KB |
testcase_07 | AC | 12 ms
9,364 KB |
testcase_08 | AC | 13 ms
9,292 KB |
testcase_09 | AC | 13 ms
9,252 KB |
testcase_10 | AC | 12 ms
9,240 KB |
testcase_11 | AC | 12 ms
9,328 KB |
testcase_12 | TLE | - |
testcase_13 | -- | - |
testcase_14 | -- | - |
testcase_15 | -- | - |
testcase_16 | -- | - |
testcase_17 | -- | - |
testcase_18 | -- | - |
testcase_19 | -- | - |
testcase_20 | -- | - |
testcase_21 | -- | - |
testcase_22 | -- | - |
testcase_23 | -- | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
testcase_29 | -- | - |
testcase_30 | -- | - |
testcase_31 | -- | - |
testcase_32 | -- | - |
testcase_33 | -- | - |
testcase_34 | -- | - |
testcase_35 | -- | - |
testcase_36 | -- | - |
ソースコード
#include<bits/stdc++.h> using namespace std; #include <atcoder/all> using namespace atcoder; using mint = modint1000000007; #define int long long struct UnionFind { vector<int> par; // par[i]:iの親の番号 (例) par[3] = 2 : 3の親が2 UnionFind(int N) : par(N) { //最初は全てが根であるとして初期化 for(int i = 0; i < N; i++) par[i] = i; } int root(int x) { // データxが属する木の根を再帰で得る:root(x) = {xの木の根} if (par[x] == x) return x; return par[x] = root(par[x]); } void unite(int x, int y) { // xとyの木を併合 int rx = root(x); //xの根をrx int ry = root(y); //yの根をry if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時:xの根rxをyの根ryにつける } bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す int rx = root(x); int ry = root(y); return rx == ry; } }; signed main() { int h,w; cin >> h >> w; vector<vector<int>> a(h,vector<int>(w)); vector<vector<pair<int,int>>> f(250001); for(int i = 0; i < h; i++) for(int j = 0; j < w; j++) cin >> a[i][j], f[a[i][j]].push_back({i,j}); int e = 200; int m = 1250; vector<UnionFind> uf(e+1,UnionFind(h*w)); UnionFind u(h*w); vector<vector<bool>> ok(h,vector<bool>(w,false)); for(int i = 1; i <= 250000; i++) { int l = f[i].size(); for(int j = 0; j < l; j++) { int x,y; tie(x,y) = f[i][j]; ok[x][y] = true; if(x != 0 && ok[x-1][y]) u.unite((x-1)*w+y,x*w+y); if(x != h-1 && ok[x+1][y]) u.unite((x+1)*w+y,x*w+y); if(y != 0 && ok[x][y-1]) u.unite(x*w+y-1,x*w+y); if(y != w-1 && ok[x][y+1]) u.unite(x*w+y+1,x*w+y); } if(i%m == 0) uf[i/m] = u; } int Q; cin >> Q; vector<int> x1(Q),x2(Q),y1(Q),y2(Q); vector<vector<int>> d(e); for(int i = 0; i < Q; i++) { cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; x1[i]--,x2[i]--,y1[i]--,y2[i]--; bool v = false; for(int j = 0; j < e; j++) { if(uf[j+1].same(x1[i]*w+y1[i],x2[i]*w+y2[i])) { d[j].push_back(i); break; } } } vector<int> ans(Q,1e18); UnionFind r(h*w); vector<vector<bool>> o(h,vector<bool>(w,false)); for(int i = 1; i <= 250000; i++) { int l = f[i].size(); for(int j = 0; j < l; j++) { int x,y; tie(x,y) = f[i][j]; o[x][y] = true; if(x != 0 && o[x-1][y]) r.unite((x-1)*w+y,x*w+y); if(x != h-1 && o[x+1][y]) r.unite((x+1)*w+y,x*w+y); if(y != 0 && o[x][y-1]) r.unite(x*w+y-1,x*w+y); if(y != w-1 && o[x][y+1]) r.unite(x*w+y+1,x*w+y); } int L = d[(i-1)/m].size(); for(int j = 0; j < L; j++) { int y = d[(i-1)/m][j]; if(r.same(x1[y]*w+y1[y],x2[y]*w+y2[y])) ans[y] = min(ans[y],i); } } for(int i = 0; i < Q; i++) cout << ans[i] << endl; }