結果
| 問題 |
No.2786 RMQ on Grid Path
|
| コンテスト | |
| ユーザー |
Today03
|
| 提出日時 | 2024-06-27 07:12:36 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,889 ms / 6,000 ms |
| コード長 | 3,384 bytes |
| コンパイル時間 | 2,877 ms |
| コンパイル使用メモリ | 213,680 KB |
| 最終ジャッジ日時 | 2025-02-22 00:46:19 |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 35 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int INF = 1e9 + 10;
const ll INFL = 4e18;
struct disjoint_set_union {
disjoint_set_union() = default;
disjoint_set_union(int n) {
par = vector<int>(n);
sz = vector<int>(n);
for (int i = 0; i < n; i++) {
par[i] = i;
sz[i] = 1;
}
forest_count = n;
}
int find(int x) {
if (par[x] == x) {
return x;
}
par[x] = find(par[x]);
return par[x];
}
void unite(int x, int y) {
x = find(x);
y = find(y);
if (x == y) {
return;
}
if (sz[x] < sz[y]) {
swap(x, y);
}
par[y] = x;
sz[x] += sz[y];
forest_count--;
}
int size(int x) {
return sz[find(x)];
}
bool same(int x, int y) {
return find(x) == find(y);
}
vector<vector<int>> groups() {
int n = par.size();
vector<vector<int>> res(n);
for (int i = 0; i < n; i++) {
res[find(i)].push_back(i);
}
res.erase(remove_if(res.begin(), res.end(), [&](const vector<int>& v) { return v.empty(); }), res.end());
return res;
}
private:
vector<int> par, sz;
int forest_count;
};
const vector<int> dx = {1, 0, -1, 0};
const vector<int> dy = {0, 1, 0, -1};
int main() {
int H, W;
cin >> H >> W;
vector<vector<int>> A(H, vector<int>(W));
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
cin >> A[i][j];
}
}
vector<vector<pair<int, int>>> idx(H * W + 1);
for (int i = 0; i < H; i++) {
for (int j = 0; j < W; j++) {
idx[A[i][j]].push_back({i, j});
}
}
int Q;
cin >> Q;
vector<tuple<int, int, int, int>> queries(Q);
for (int i = 0; i < Q; i++) {
int r1, c1, r2, c2;
cin >> r1 >> c1 >> r2 >> c2;
r1--;
c1--;
r2--;
c2--;
queries[i] = {r1, c1, r2, c2};
}
// 並列二分探索
vector<int> lo(Q, 0), hi(Q, H * W + 1);
while (true) {
bool finish = true;
vector<vector<int>> mid_idx(H * W + 1);
for (int i = 0; i < Q; i++) {
if (hi[i] - lo[i] > 1) {
finish = false;
int mid = (lo[i] + hi[i]) / 2;
mid_idx[mid].push_back(i);
}
}
if (finish) {
break;
}
disjoint_set_union dsu(H * W);
for (int i = 0; i <= H * W; i++) {
for (auto [r, c] : idx[i]) {
for (int j = 0; j < 4; j++) {
int nr = r + dx[j];
int nc = c + dy[j];
if (nr < 0 || nr >= H || nc < 0 || nc >= W) {
continue;
}
if (A[nr][nc] <= i) {
dsu.unite(r * W + c, nr * W + nc);
}
}
}
for (int q : mid_idx[i]) {
auto [r1, c1, r2, c2] = queries[q];
if (dsu.same(r1 * W + c1, r2 * W + c2)) {
hi[q] = i;
} else {
lo[q] = i;
}
}
}
}
for (int i = 0; i < Q; i++) {
cout << hi[i] << '\n';
}
}
Today03