1. 程式人生 > >Codeforces 845E Fire in the City 線段樹

Codeforces 845E Fire in the City 線段樹

fir for ORC pan lin i++ lse temp rhs

Fire in the City

二分答案, 用掃描先加線段樹去check

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define
SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 998244353; const double eps = 1e-8; const double PI = acos(-1
); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true
: false;} template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} vector<int> oo, gg; int getPos(int x) { return lower_bound(ALL(oo), x) - oo.begin() + 1; } namespace SGT { #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 int a[N << 2], lazy[N << 2]; inline void push(int rt) { if(lazy[rt]) { a[rt << 1] += lazy[rt]; a[rt << 1 | 1] += lazy[rt]; lazy[rt << 1] += lazy[rt]; lazy[rt << 1 | 1] += lazy[rt]; lazy[rt] = 0; } } void build(int l, int r, int rt) { a[rt] = lazy[rt] = 0; if(l == r) return; int mid = l + r >> 1; build(lson); build(rson); } void update(int L, int R, int v, int l, int r, int rt) { if(R < l || r < L) return; if(L <= l && r <= R) { a[rt] += v; lazy[rt] += v; return; } push(rt); int mid = l + r >> 1; update(L, R, v, lson); update(L, R, v, rson); a[rt] = min(a[rt << 1], a[rt << 1 | 1]); } int getMinId(int l, int r, int rt) { if(a[rt] > 0) return -1; if(l == r) return oo[l - 1]; push(rt); int mid = l + r >> 1; if(a[rt << 1] == 0) return getMinId(lson); else return getMinId(rson); } int getMaxId(int l, int r, int rt) { if(a[rt] > 0) return -1; if(l == r) return oo[l] - 1; push(rt); int mid = l + r >> 1; if(a[rt << 1 | 1] == 0) return getMaxId(rson); else return getMaxId(lson); } } struct Point { Point(int x = 0, int y = 0) : x(x), y(y) {} int x, y; }; struct Rec { Point a, b; }; Rec mergeRec(const Rec& lhs, const Rec& rhs) { Rec ans; ans.a.x = max(lhs.a.x, rhs.a.x); ans.a.y = max(lhs.a.y, rhs.a.y); ans.b.x = min(lhs.b.x, rhs.b.x); ans.b.y = min(lhs.b.y, rhs.b.y); return ans; } inline bool ok(const Rec& r) { return r.a.x <= r.b.x && r.a.y <= r.b.y; } int n, m, k; Point a[N]; vector<Rec> vc, tmp; inline void go(Rec& now, Point p, int T) { now = mergeRec(now, Rec{Point(p.x - T, p.y - T), Point(p.x + T, p.y + T)}); } bool check(int T) { oo.clear(); gg.clear(); gg.push_back(1); gg.push_back(m + 1); oo.push_back(1); oo.push_back(n + 1); for(int i = 1; i <= k; i++) { oo.push_back(max(1, a[i].x - T)); oo.push_back(min(n + 1, a[i].x + T + 1)); gg.push_back(max(1, a[i].y - T)); gg.push_back(min(m + 1, a[i].y + T + 1)); } sort(oo.begin(), oo.end()); oo.erase(unique(ALL(oo)), oo.end()); sort(gg.begin(), gg.end()); gg.erase(unique(ALL(gg)), gg.end()); SGT::build(1, SZ(oo) - 1, 1); Rec now = Rec{Point(1, 1), Point(n, m)}; for(int i = 0; i < SZ(gg); i++) { if(i > 0) { int mnx = SGT::getMinId(1, SZ(oo) - 1, 1); int mxx = SGT::getMaxId(1, SZ(oo) - 1, 1); if(~mnx) { go(now, Point(mnx, gg[i - 1]), T); go(now, Point(mnx, gg[i] - 1), T); go(now, Point(mxx, gg[i - 1]), T); go(now, Point(mxx, gg[i] - 1), T); } } if(i == SZ(gg) - 1) break; for(int j = 1; j <= k; j++) { if(max(1, a[j].y - T) == gg[i]) { SGT::update(getPos(max(1, a[j].x - T)), getPos(min(n + 1, a[j].x + T + 1)) - 1, 1, 1, SZ(oo) - 1, 1); } if(min(m + 1, a[j].y + T + 1) == gg[i]) { SGT::update(getPos(max(1, a[j].x - T)), getPos(min(n + 1, a[j].x + T + 1)) - 1, -1, 1, SZ(oo) - 1, 1); } } } return ok(now); } int main() { scanf("%d%d%d", &n, &m, &k); for(int i = 1; i <= k; i++) scanf("%d%d", &a[i].x, &a[i].y); int low = 0, high = max(n, m), ans = high; while(low <= high) { int mid = low + high >> 1; if(check(mid)) high = mid - 1, ans = mid; else low = mid + 1; } printf("%d\n", ans); return 0; } /* */

Codeforces 845E Fire in the City 線段樹