[LOJ2334] 「JOI 2017 Final」JOIOI 王国(二分答案)

时间:2025-03-09 11:56:35
#include<bits/stdc++.h> using namespace std; int read() { int _ = 0, __ = getchar(), ___ = 1; for(; !isdigit(__); __ = getchar()) if(__ == '-') ___ = -1; for(; isdigit(__); __ = getchar()) _ = (_ << 3) + (_ << 1) + (__ ^ 48); return _ * ___; } const int N = 2000 + 7; int premax[N][N], sufmax[N][N], premin[N][N], sufmin[N][N]; int tmp[N], n, m, mn = tmp[0] = 2e9, mx = -2e9; bool check1(int lim) { int mnlim = mn + lim, mxlim = mx - lim, lst = m; for(int i = 1; i <= n; ++ i) { tmp[i] = 0; for(int j = 1; j <= m; ++ j) if(premax[i][j] <= mnlim) tmp[i] = j; } for(int i = n; i >= 1; -- i) { lst = min(tmp[i], lst); if(sufmin[i][lst + 1] < mxlim) return false; } return true; } bool check2(int lim) { int mnlim = mn + lim, mxlim = mx - lim, lst = m; for(int i = 1; i <= n; ++ i) { tmp[i] = 0; for(int j = 1; j <= m; ++ j) if(premin[i][j] >= mxlim) tmp[i] = j; } for(int i = n; i >= 1; -- i) { lst = min(tmp[i], lst); if(sufmax[i][lst + 1] > mnlim) return false; } return true; } bool check3(int lim) { int mnlim = mn + lim, mxlim = mx - lim, lst = m; for(int i = 1; i <= n; ++ i) { tmp[i] = 0; for(int j = 1; j <= m; ++ j) if(premax[i][j] <= mnlim) tmp[i] = j; } for(int i = 1; i <= n; ++ i) { lst = min(tmp[i], lst); if(sufmin[i][lst + 1] < mxlim) return false; } return true; } bool check4(int lim) { int mnlim = mn + lim, mxlim = mx - lim, lst = m; for(int i = 1; i <= n; ++ i) { tmp[i] = 0; for(int j = 1; j <= m; ++ j) if(premin[i][j] >= mxlim) tmp[i] = j; } for(int i = 1; i <= n; ++ i) { lst = min(tmp[i], lst); if(sufmax[i][lst + 1] > mnlim) return false; } return true; } bool check(int lim) { if(check1(lim) || check2(lim) || check3(lim) || check4(lim)) return true; return false; } int main() { //freopen("", "r", stdin); //freopen("", "w", stdout); n = read(), m = read(); for(int i = 1; i <= n; ++ i) { for(int j = 1; j <= m; ++ j) { premax[i][j] = premin[i][j] = sufmax[i][j] = sufmin[i][j] = read(); if(premax[i][j] > mx) mx = premax[i][j]; if(premin[i][j] < mn) mn = premin[i][j]; } sufmin[i][m + 1] = 2e9; } for(int i = 1; i <= n; ++ i) { for(int j = 2; j <= m; ++ j) { premax[i][j] = max(premax[i][j - 1], premax[i][j]); premin[i][j] = min(premin[i][j - 1], premin[i][j]); } for(int j = m; j >= 2; -- j) { sufmax[i][j - 1] = max(sufmax[i][j], sufmax[i][j - 1]); sufmin[i][j - 1] = min(sufmin[i][j], sufmin[i][j - 1]); } } int l = 0, r = mx - mn, ans; while(l <= r) { int mid = (l + r) >> 1; if(check(mid)) ans = mid, r = mid - 1; else l = mid + 1; } printf("%d\n", ans); return 0; }