Submission #1075781

#TimeUsernameProblemLanguageResultExecution timeMemory
1075781Joshua_AnderssonTeams (IOI15_teams)C++14
34 / 100
1775 ms524288 KiB
#include "teams.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll linf = ll(1e18); typedef vector<int> vi; typedef vector<vi> vvi; typedef pair<int, int> p2; #define rep(i, high) for (int i = 0; i < high; i++) #define repp(i, low, high) for (int i = low; i < high; i++) #define repe(i, container) for (auto& i : container) #define sz(container) ((int)container.size()) #define all(x) begin(x),end(x) #if _LOCAL #define assert(x) if (!(x)) __debugbreak() #endif struct node { node* lc=0, * rc=0; int sum = 0; node(node* lc, node* rc, int s) : lc(lc), rc(rc), sum(s) {} }; node* build(int l, int r) { if (l==r) { return new node(0, 0, 0); } else { int mid = (l + r) / 2; return new node(build(l, mid), build(mid + 1, r), 0); } } node* update(node* x, int l, int r, int i, int s) { if (l==r) { return new node(0, 0, x->sum+s); } else { int mid = (l + r) / 2; node* ret = new node(x->lc, x->rc, 0); if (i <= mid) ret->lc = update(x->lc, l, mid, i, s); else ret->rc = update(x->rc, mid + 1, r, i, s); ret->sum = ret->lc->sum + ret->rc->sum; return ret; } } int query(node* x, int l, int r, int ql, int qr) { if (l > qr || r < ql) return 0; if (l >= ql && r <= qr) return x->sum; int mid = (l + r) / 2; return query(x->lc, l, mid, ql, qr) + query(x->rc, mid + 1, r, ql, qr); } int n; typedef pair<double, int> pt; vector<p2> pts; node* roots[int(1e5)]; void init(int N, int A[], int B[]) { n = N; vi a(n); vi b(n); rep(i, N) a[i] = A[i], b[i] = B[i]; rep(i, n) { pts.emplace_back(a[i], b[i]); } sort(all(pts), [](p2 a, p2 b) { return a.second < b.second; }); node* root = build(0, n - 1); rep(i, n) { root = roots[i] = update(root, 0, n - 1, pts[i].first, 1); } } int rectangle_sum(int xlo, int xhi, int yhi) { return query(roots[yhi], 0, n - 1, xlo, xhi); } struct tnode { p2 corner; int value, sum=0, prio, cnt=1; tnode *l=0, *r=0; tnode(p2 corner, int value) : corner(corner), prio(rand()), value(value) {} }; typedef tnode* pnode; int get_sum(pnode x) { return x ? x->sum : 0; } int get_cnt(pnode x) { return x ? x->cnt : 0; } void pull(pnode x) { if (!x) return; x->sum = get_sum(x->l) + get_sum(x->r) + x->value; x->cnt = get_cnt(x->l) + get_cnt(x->r) + 1; } void split(pnode x, pnode& l, pnode& r, int s) { if (!x) return void(l = r = 0); if (x->corner.first > s) split(x->l, l, x->l, s), r = x; else split(x->r, x->r, r, s), l = x; pull(x); } void merge(pnode& x, pnode l, pnode r) { if (!l || !r) x = l ? l : r; else if (l->prio < r->prio) merge(r->l, l, r->l), x = r; else merge(l->r, l->r, r), x = l; pull(x); } p2 get_corner(pnode x, int i, int add = 0) { int node_i = add + get_cnt(x->l); if (node_i == i) return x->corner; if (node_i > i) return get_corner(x->l, i, add); return get_corner(x->r, i, add + get_cnt(x->l) + 1); } int sum(pnode& root, int xhi, int ylo, int yhi) { int prev = -1; int taken = 0; int lo = -1; int hi = get_cnt(root); while (lo + 1 < hi) { int mid = (lo + hi) / 2; if (get_corner(root, mid).second <= yhi) { hi = mid; } else lo = mid; } int s = 0; if (root) { pnode l, r; int lo = -2; if (hi) lo = get_corner(root, hi - 1).first; split(root, l, r, lo); if (r) s = r->sum; merge(root, l, r); } if (hi > 0 && get_cnt(root)) { s += rectangle_sum(0, get_corner(root, hi-1).first, yhi); } return rectangle_sum(0, xhi, yhi) - s; } const int inf = int(2e9); p2 invalid = p2(-inf, -inf); p2 lower_bound(pnode root, int x) { if (!root) return invalid; if (root->corner.first >= x) { p2 left_result = lower_bound(root->l, x); if (left_result != invalid) return left_result; else return root->corner; } else { return lower_bound(root->r, x); } } p2 rev_bound(pnode root, int x) { if (!root) return invalid; p2 result = invalid; if (root->corner.first <= x) { result = root->corner; p2 right_result = rev_bound(root->r, x); if (right_result != invalid) result = right_result; } else result = rev_bound(root->l, x); return result; } int can(int m, int K[]) { vi k(m); rep(i, m) k[i] = K[i]; sort(all(k)); pnode hull = 0; auto insert = [&](p2 new_corner) { p2 lo = lower_bound(hull, new_corner.first); if ((new_corner.first <= lo.first && new_corner.second <= lo.second)) { // dominated } else { while (1) { p2 p = rev_bound(hull, new_corner.first); if (p == invalid) break; assert(p.first <= new_corner.first); if (p.second <= new_corner.second) { pnode l, mid, r; split(hull, l, r, p.first); split(hull, l, mid, p.first - 1); merge(hull, l, r); } else break; } p2 lo = rev_bound(hull, new_corner.first); int s = rectangle_sum((lo.first!=-inf)?lo.first+1:0, new_corner.first, new_corner.second); pnode new_node = new tnode(new_corner, s); pnode l, r; split(hull, l, r, new_corner.first); merge(hull, l, new_node); merge(hull, hull, r); } }; int lo = 0; rep(i, m) { while (lo < sz(pts) && pts[lo].second < k[i]) { insert(p2(k[i], lo)); lo++; } if (sum(hull, k[i], 0, n-1)<k[i]) { return 0; } int lob = lo-1; int hib = n; while (lob+1<hib) { int mid = (lob + hib) / 2; if (sum(hull, k[i], lo, mid) < k[i]) { lob = mid; } else hib = mid; } p2 new_corner = p2(k[i], hib); insert(new_corner); } return 1; }

Compilation message (stderr)

teams.cpp: In constructor 'node::node(node*, node*, int)':
teams.cpp:27:23: warning: declaration of 'rc' shadows a member of 'node' [-Wshadow]
   27 |  node(node* lc, node* rc, int s) : lc(lc), rc(rc), sum(s) {}
      |                 ~~~~~~^~
teams.cpp:25:16: note: shadowed declaration is here
   25 |  node* lc=0, * rc=0;
      |                ^~
teams.cpp:27:13: warning: declaration of 'lc' shadows a member of 'node' [-Wshadow]
   27 |  node(node* lc, node* rc, int s) : lc(lc), rc(rc), sum(s) {}
      |       ~~~~~~^~
teams.cpp:25:8: note: shadowed declaration is here
   25 |  node* lc=0, * rc=0;
      |        ^~
teams.cpp: In constructor 'node::node(node*, node*, int)':
teams.cpp:27:23: warning: declaration of 'rc' shadows a member of 'node' [-Wshadow]
   27 |  node(node* lc, node* rc, int s) : lc(lc), rc(rc), sum(s) {}
      |                 ~~~~~~^~
teams.cpp:25:16: note: shadowed declaration is here
   25 |  node* lc=0, * rc=0;
      |                ^~
teams.cpp:27:13: warning: declaration of 'lc' shadows a member of 'node' [-Wshadow]
   27 |  node(node* lc, node* rc, int s) : lc(lc), rc(rc), sum(s) {}
      |       ~~~~~~^~
teams.cpp:25:8: note: shadowed declaration is here
   25 |  node* lc=0, * rc=0;
      |        ^~
teams.cpp: In constructor 'node::node(node*, node*, int)':
teams.cpp:27:23: warning: declaration of 'rc' shadows a member of 'node' [-Wshadow]
   27 |  node(node* lc, node* rc, int s) : lc(lc), rc(rc), sum(s) {}
      |                 ~~~~~~^~
teams.cpp:25:16: note: shadowed declaration is here
   25 |  node* lc=0, * rc=0;
      |                ^~
teams.cpp:27:13: warning: declaration of 'lc' shadows a member of 'node' [-Wshadow]
   27 |  node(node* lc, node* rc, int s) : lc(lc), rc(rc), sum(s) {}
      |       ~~~~~~^~
teams.cpp:25:8: note: shadowed declaration is here
   25 |  node* lc=0, * rc=0;
      |        ^~
teams.cpp: In lambda function:
teams.cpp:85:29: warning: declaration of 'b' shadows a previous local [-Wshadow]
   85 |  sort(all(pts), [](p2 a, p2 b)
      |                          ~~~^
teams.cpp:78:5: note: shadowed declaration is here
   78 |  vi b(n);
      |     ^
teams.cpp:85:23: warning: declaration of 'a' shadows a previous local [-Wshadow]
   85 |  sort(all(pts), [](p2 a, p2 b)
      |                    ~~~^
teams.cpp:77:5: note: shadowed declaration is here
   77 |  vi a(n);
      |     ^
teams.cpp: In constructor 'tnode::tnode(p2, int)':
teams.cpp:106:23: warning: declaration of 'value' shadows a member of 'tnode' [-Wshadow]
  106 |  tnode(p2 corner, int value) : corner(corner), prio(rand()), value(value) {}
      |                   ~~~~^~~~~
teams.cpp:104:6: note: shadowed declaration is here
  104 |  int value, sum=0, prio, cnt=1;
      |      ^~~~~
teams.cpp:106:11: warning: declaration of 'corner' shadows a member of 'tnode' [-Wshadow]
  106 |  tnode(p2 corner, int value) : corner(corner), prio(rand()), value(value) {}
      |        ~~~^~~~~~
teams.cpp:103:5: note: shadowed declaration is here
  103 |  p2 corner;
      |     ^~~~~~
teams.cpp:104:20: warning: 'tnode::prio' will be initialized after [-Wreorder]
  104 |  int value, sum=0, prio, cnt=1;
      |                    ^~~~
teams.cpp:104:6: warning:   'int tnode::value' [-Wreorder]
  104 |  int value, sum=0, prio, cnt=1;
      |      ^~~~~
teams.cpp:106:2: warning:   when initialized here [-Wreorder]
  106 |  tnode(p2 corner, int value) : corner(corner), prio(rand()), value(value) {}
      |  ^~~~~
teams.cpp: In constructor 'tnode::tnode(p2, int)':
teams.cpp:106:23: warning: declaration of 'value' shadows a member of 'tnode' [-Wshadow]
  106 |  tnode(p2 corner, int value) : corner(corner), prio(rand()), value(value) {}
      |                   ~~~~^~~~~
teams.cpp:104:6: note: shadowed declaration is here
  104 |  int value, sum=0, prio, cnt=1;
      |      ^~~~~
teams.cpp:106:11: warning: declaration of 'corner' shadows a member of 'tnode' [-Wshadow]
  106 |  tnode(p2 corner, int value) : corner(corner), prio(rand()), value(value) {}
      |        ~~~^~~~~~
teams.cpp:103:5: note: shadowed declaration is here
  103 |  p2 corner;
      |     ^~~~~~
teams.cpp: In constructor 'tnode::tnode(p2, int)':
teams.cpp:106:23: warning: declaration of 'value' shadows a member of 'tnode' [-Wshadow]
  106 |  tnode(p2 corner, int value) : corner(corner), prio(rand()), value(value) {}
      |                   ~~~~^~~~~
teams.cpp:104:6: note: shadowed declaration is here
  104 |  int value, sum=0, prio, cnt=1;
      |      ^~~~~
teams.cpp:106:11: warning: declaration of 'corner' shadows a member of 'tnode' [-Wshadow]
  106 |  tnode(p2 corner, int value) : corner(corner), prio(rand()), value(value) {}
      |        ~~~^~~~~~
teams.cpp:103:5: note: shadowed declaration is here
  103 |  p2 corner;
      |     ^~~~~~
teams.cpp: In function 'int sum(tnode*&, int, int, int)':
teams.cpp:169:7: warning: declaration of 'lo' shadows a previous local [-Wshadow]
  169 |   int lo = -2;
      |       ^~
teams.cpp:152:6: note: shadowed declaration is here
  152 |  int lo = -1;
      |      ^~
teams.cpp:150:6: warning: unused variable 'prev' [-Wunused-variable]
  150 |  int prev = -1;
      |      ^~~~
teams.cpp:151:6: warning: unused variable 'taken' [-Wunused-variable]
  151 |  int taken = 0;
      |      ^~~~~
teams.cpp:148:35: warning: unused parameter 'ylo' [-Wunused-parameter]
  148 | int sum(pnode& root, int xhi, int ylo, int yhi)
      |                               ~~~~^~~
teams.cpp: In lambda function:
teams.cpp:247:7: warning: declaration of 'lo' shadows a previous local [-Wshadow]
  247 |    p2 lo = rev_bound(hull, new_corner.first);
      |       ^~
teams.cpp:226:6: note: shadowed declaration is here
  226 |   p2 lo = lower_bound(hull, new_corner.first);
      |      ^~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...