Submission #90508

#TimeUsernameProblemLanguageResultExecution timeMemory
90508jasony123123Kosta (COI14_kosta)C++11
100 / 100
1664 ms30124 KiB
#pragma optimize( "/Ox", on ) #define _CRT_SECURE_NO_WARNINGS #include <bits/stdc++.h> //#include <ext/pb_ds/tree_policy.hpp> //#include <ext/pb_ds/assoc_container.hpp> using namespace std; //using namespace __gnu_pbds; #define FOR(i,start,end) for(int i=start;i<(int)(end);i++) #define FORE(i,start,end) for(int i=start;i<=(int)end;i++) #define RFOR(i,start,end) for(int i = start; i>end; i--) #define RFORE(i,start,end) for(int i = start; i>=end; i--) #define all(a) a.begin(), a.end() #define mt make_tuple #define mp make_pair #define v vector #define sf scanf #define pf printf #define dvar(x) cout << #x << " := " << x << "\n" #define darr(x,n) FOR(i,0,n) cout << #x << "[" << i << "]" << " := " << x[i] << "\n" typedef long long ll; typedef long double ld; typedef pair<int, int > pii; typedef pair<ll, ll> pll; //template <class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; template<class T> void minn(T &a, T b) { a = min(a, b); } template<class T> void maxx(T &a, T b) { a = max(a, b); } void io() { #ifdef LOCAL_PROJECT freopen("input.in", "r", stdin); freopen("output.out", "w", stdout); #else /* online submission */ #endif ios_base::sync_with_stdio(false); cin.tie(NULL); } const ll MOD = 1000000007LL; const ll PRIME = 105943LL; const int INF = 1e8; /****************************************************************/ /* Find minimum D st K points with boxes of 2D sides cover all points */ struct BBox { int x1, y1, x2, y2; BBox() { x1 = INF, y1 = INF, x2 = -INF, y2 = -INF; } void upd(pii a) { minn(x1, a.first); maxx(x2, a.first); minn(y1, a.second); maxx(y2, a.second); } void upd(BBox b) { minn(x1, b.x1); minn(y1, b.y1); maxx(x2, b.x2); maxx(y2, b.y2); } }; struct Event {// f: {0, point} {1,box left/bot} {2, box right, top} int p, f, idx; Event(int a, int b, int c) { p = a, f = b, idx = c; } inline bool operator<(const Event &b) const { return p < b.p; } }; template<class T, int L> struct Bit { T bit[L + 1]; Bit() {} void clr() { memset(bit, 0, sizeof bit); } void upd(int k, T val) { for (k++; k <= L; k += (k&-k)) bit[k] += val; } T query(int k) { T temp = 0; for (k++; k > 0; k -= (k&-k)) temp += bit[k]; return temp; } T query(int l, int r) { return query(r) - query(l - 1); } }; const int MAXN = 200000; int K, N; pii pnts[MAXN]; BBox rem[MAXN]; Bit<int, 4000199> cnt; void add(int x, int y, int val) { x += 2e6; y += 2e6; cnt.upd(x, val); cnt.upd(y + 1, -val); } int query(int x) { x += 2e6; return cnt.query(x); } void reset() { fill(rem, rem + N, BBox()); cnt.clr(); } void sweep(int pFlag, int bFlag, v<Event> &lst) { BBox cur; FOR(i, 0, lst.size()) { v<int> curidx[3]; int pc = lst[i].p; curidx[lst[i].f].push_back(lst[i].idx); while (i + 1 < lst.size() && lst[i + 1].p == pc) { i++; curidx[lst[i].f].push_back(lst[i].idx); } // process boxes first, then points for (int b : curidx[bFlag]) rem[b].upd(cur); for (int p : curidx[pFlag]) cur.upd(pnts[p]); } } void initRemBox(int d) { v<Event> lstX, lstY; FOR(i, 0, N) { lstX.push_back(Event(pnts[i].first, 0, i)); lstX.push_back(Event(pnts[i].first - d, 1, i)); lstX.push_back(Event(pnts[i].first + d, 2, i)); lstY.push_back(Event(pnts[i].second, 0, i)); lstY.push_back(Event(pnts[i].second - d, 1, i)); lstY.push_back(Event(pnts[i].second + d, 2, i)); } sort(all(lstX)); sweep(0, 1, lstX); reverse(all(lstX)); sweep(0, 2, lstX); sort(all(lstY)); sweep(0, 1, lstY); reverse(all(lstY)); sweep(0, 2, lstY); } BBox toNeeded(BBox b, int d) { BBox ans; ans.x1 = b.x2 - d; ans.x2 = b.x1 + d; ans.y1 = b.y2 - d; ans.y2 = b.y1 + d; return ans; } bool isOk(BBox b) { return b.x1 <= b.x2 && b.y1 <= b.y2; } pii works(int d) { initRemBox(d); v<Event> lst; FOR(i, 0, N) { if (rem[i].x1 == INF && rem[i].x2 == -INF) { return{ i, i }; } rem[i] = toNeeded(rem[i], d); if (isOk(rem[i])) { lst.push_back(Event(rem[i].x1, 1, i)); lst.push_back(Event(rem[i].x2, 2, i)); } lst.push_back(Event(pnts[i].first, 0, i)); } // see if exists a point inside of a box BIT+reverse lookup sort(all(lst)); FOR(i, 0, lst.size()) { v<int> curidx[3]; int pc = lst[i].p; curidx[lst[i].f].push_back(lst[i].idx); while (i + 1 < lst.size() && lst[i + 1].p == pc) { i++; curidx[lst[i].f].push_back(lst[i].idx); } for (int b : curidx[1]) // starting add(rem[b].y1, rem[b].y2, 1); for (int p : curidx[0]) {// points if (query(pnts[p].second) > 0) { // this point(p) is inside something RFORE(j, i, 0) if (lst[j].f == 1) { int b = lst[j].idx; if (rem[b].y1 <= pnts[p].second && pnts[p].second <= rem[b].y2) { return{ b,p }; } } // assert(0); } } for (int b : curidx[2]) // ending add(rem[b].y1, rem[b].y2, -1); } return{ -1,-1 }; } void solve2() { pii ans; int lo = 0, hi = 2e6 + 1; while (lo<hi) { int mid = (hi + lo) / 2; reset(); ans = works(mid); if (ans == mp(-1, -1)) { lo = mid + 1; } else { hi = mid; } } ans = works(lo); cout << lo << "\n" << ans.first + 1 << " " << ans.second + 1 << "\n"; } void solve1() { BBox b; FOR(i, 0, N) b.upd(pnts[i]); pii ans = { INF, -1 }; FOR(i, 0, N) { int d = max(max(abs(b.x1 - pnts[i].first), abs(b.x2 - pnts[i].first)), max(abs(b.y1 - pnts[i].second), abs(b.y2 - pnts[i].second))); minn(ans, { d,i }); } cout << ans.first << "\n" << ans.second + 1 << "\n"; } int main() { io(); cin >> K >> N; BBox entire; FOR(i, 0, N) { int x, y; cin >> x >> y; pnts[i].first = x + y; pnts[i].second = x - y; entire.upd(pnts[i]); } FOR(i, 0, N) { pnts[i].first -= entire.x1; pnts[i].second -= entire.y1; } if (K == 1) solve1(); else solve2(); return 0; }

Compilation message (stderr)

kosta.cpp:1:0: warning: ignoring #pragma optimize  [-Wunknown-pragmas]
 #pragma optimize( "/Ox", on )
 
kosta.cpp: In function 'void sweep(int, int, std::vector<Event>&)':
kosta.cpp:130:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   while (i + 1 < lst.size() && lst[i + 1].p == pc) {
          ~~~~~~^~~~~~~~~~~~
kosta.cpp: In function 'pii works(int)':
kosta.cpp:196:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   while (i + 1 < lst.size() && lst[i + 1].p == pc) {
          ~~~~~~^~~~~~~~~~~~
#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...
#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...