結果
| 問題 |
No.2786 RMQ on Grid Path
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-08-31 03:18:28 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,499 ms / 6,000 ms |
| コード長 | 2,460 bytes |
| コンパイル時間 | 6,009 ms |
| コンパイル使用メモリ | 324,548 KB |
| 実行使用メモリ | 58,668 KB |
| 最終ジャッジ日時 | 2024-08-31 03:19:08 |
| 合計ジャッジ時間 | 39,426 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 35 |
ソースコード
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using ll = long long;
using ld = long double;
using mint = atcoder::modint1000000007;
const ll inf = 9e18;
struct UnionFind{
vector<ll> par;
vector<ll> size;
UnionFind(ll n){
par.resize(2*(n+1),-1);
size.resize(2*(n+1),1);
}
ll root(ll x){
if (par[x]==-1) return x;
return par[x]=root(par[x]);
}
void unite(ll u,ll v){
ll uu=root(u),vv=root(v);
if(uu==vv){
return;
}
if(size[uu]<size[vv]){
par[uu]=vv;
size[vv]+=size[uu];
}else{
par[vv]=uu;
size[uu]+=size[vv];
}
return;
}
bool same(ll u,ll v){
return root(u)==root(v);
}
ll out_size(ll n){
return size[root(n)];
}
};
bool in_out(ll x,ll y,ll h,ll w){
return 0<=x and x<h and 0<=y and y<w;
}
ll di[8]={1,-1,0,0,1,1,-1,-1};
ll dj[8]={0,0,1,-1,1,-1,-1,1};
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
ll h,w;
cin >> h >> w;
vector a(h,vector<ll>(w));
for(ll i=0;i<h;i++){
for(ll j=0;j<w;j++){
cin >> a[i][j];
}
}
vector edge(h*w+1,vector<array<ll,4>>(0));
for(ll i=0;i<h;i++){
for(ll j=0;j<w;j++){
if(i+1<h){
ll cost=max(a[i][j],a[i+1][j]);
edge[cost].push_back({i,j,i+1,j});
}
if(j+1<w){
ll cost=max(a[i][j],a[i][j+1]);
edge[cost].push_back({i,j,i,j+1});
}
}
}
ll q;
cin >> q;
vector<array<ll,4>> sg(q);
for(auto&[si,sj,gi,gj]:sg){
cin >> si >> sj >> gi >> gj;
si--,sj--,gi--,gj--;
}
vector<ll> ok(q,h*w+2),ng(q,0);
auto check=[&]()->bool {
for(ll i=0;i<q;i++){
if(ok[i]-ng[i]>1) return true;
}
return false;
};
while(check()){
vector mid(h*w+1,vector<ll>(0));
for(ll i=0;i<q;i++){
ll t=(ok[i]+ng[i])/2;
mid[t].push_back(i);
}
UnionFind uf(h*w);
for(ll t=0;t<=h*w;t++){
for(auto[i,j,x,y]:edge[t]){
uf.unite(x*w+y,i*w+j);
}
for(ll i:mid[t]){
auto[si,sj,gi,gj]=sg[i];
if(uf.same(si*w+sj,gi*w+gj)) ok[i]=t;
else ng[i]=t;
}
}
}
for(ll i=0;i<q;i++){
cout << ok[i] << endl;
}
}