Submission #680675

#TimeUsernameProblemLanguageResultExecution timeMemory
68067579brueLand of the Rainbow Gold (APIO17_rainbow)C++17
100 / 100
1300 ms468740 KiB
#include "rainbow.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; struct PST{ struct Node{ Node *lc, *rc; int sum; Node(int l, int r){ sum = 0; if(l==r) lc = rc = nullptr; else{ int m = (l+r)/2; lc = new Node(l, m); rc = new Node(m+1, r); } } Node(Node *lc, Node *rc, int sum): lc(lc), rc(rc), sum(sum){} ~Node(){ if(lc) delete lc; if(rc) delete rc; } int query(int l, int r, int s, int e){ if(r<s || e<l) return 0; if(s<=l && r<=e) return sum; int m = (l+r)>>1; return lc->query(l, m, s, e) + rc->query(m+1, r, s, e); } Node* update(int l, int r, int x, int v){ if(l==r){ Node* tmp = new Node(lc, rc, sum + v); return tmp; } int m = (l+r)>>1; Node* tmp = new Node(lc, rc, sum+v); if(x<=m) tmp->lc = lc->update(l, m, x, v); else tmp->rc = rc->update(m+1, r, x, v); return tmp; } } *root = nullptr; int n; PST(){} Node *yHistory[200002]; int yMaximum; void init(int _n){ n = _n; root = new Node(0, n); for(int i=0; i<=200001; i++) yHistory[i] = nullptr; yMaximum = 0; } void update(int x, int y){ while(yMaximum < y) yHistory[yMaximum++] = root; root = root->update(0, n, x, 1); } void finish(){ while(yMaximum < 200001) yHistory[yMaximum++] = root; } int query(int xl, int xr, int yl, int yr){ // printf("(%d - %d) = %d\n", yHistory[yr]->query(0, n, xl, xr), (yl == 0 ? 0 : yHistory[yl-1]->query(0, n, xl, xr))); return yHistory[yr]->query(0, n, xl, xr) - (yl == 0 ? 0 : yHistory[yl-1]->query(0, n, xl, xr)); } } vpst, ehpst, evpst, fpst; struct Point{ int x, y; Point(){} Point(int x, int y): x(x), y(y){} bool operator<(const Point &r)const{ if(y!=r.y) return y<r.y; return x<r.x; } bool operator==(const Point &r)const{ return x==r.x && y==r.y; } }; int N, M; int xMin = 1e9, xMax = -1e9, yMin = 1e9, yMax = -1e9; vector<Point> vvec, ehvec, evvec, fvec; void check(int X, int Y){ xMin = min(xMin, X), yMin = min(yMin, Y); xMax = max(xMax, X), yMax = max(yMax, Y); vvec.push_back(Point(X, Y)); if(Y!=1) ehvec.push_back(Point(X, Y-1)); if(Y!=M) ehvec.push_back(Point(X, Y)); if(X!=1) evvec.push_back(Point(X-1, Y)); if(X!=N) evvec.push_back(Point(X, Y)); if(Y!=1 && X!=1) fvec.push_back(Point(X-1, Y-1)); if(Y!=M && X!=1) fvec.push_back(Point(X-1, Y)); if(Y!=1 && X!=N) fvec.push_back(Point(X, Y-1)); if(Y!=M && X!=N) fvec.push_back(Point(X, Y)); } void update(PST &pst, vector<Point> &vec){ sort(vec.begin(), vec.end()); vec.erase(unique(vec.begin(), vec.end()), vec.end()); pst.init(N); for(Point p: vec){ pst.update(p.x, p.y); } pst.finish(); } void init(int R, int C, int sr, int sc, int K, char *S){ N = R, M = C; vpst.init(N); ehpst.init(N); evpst.init(N); fpst.init(N); int x = sr, y = sc; check(x, y); for(int i=0; i<K; i++){ if(S[i] == 'N') x--; else if(S[i] == 'E') y++; else if(S[i] == 'W') y--; else x++; check(x, y); } update(vpst, vvec); update(ehpst, ehvec); update(evpst, evvec); update(fpst, fvec); } int colour(int x1, int y1, int x2, int y2){ ll V = ll(x2-x1+1) * ll(y2-y1+1) - vpst.query(x1, x2, y1, y2); ll EH = ll(x2-x1+1) * ll(y2-y1) - ehpst.query(x1, x2, y1, y2-1); ll EV = ll(x2-x1) * ll(y2-y1+1) - evpst.query(x1, x2-1, y1, y2); ll F = ll(x2-x1) * ll(y2-y1) - fpst.query(x1, x2-1, y1, y2-1); if(x1 < xMin && xMax < x2 && y1 < yMin && yMax < y2) F++; // printf("%lld %lld %lld %lld\n", V, EH, EV, F); return V-(EH+EV)+F; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...