Submission #281652

#TimeUsernameProblemLanguageResultExecution timeMemory
281652evpipisPyramid Base (IOI08_pyramid_base)C++11
100 / 100
2598 ms246024 KiB
#include <bits/stdc++.h> using namespace std; #define pb push_back typedef long long ll; const int len = 1e6+4; const ll inf = 1e16; int cost[len], n, m, bud, q; vector<int> buck[len]; struct rectangle{ int x1, x2, y1, y2; } rec[len]; struct{ struct node{ ll mn, lazy; node(ll mn_ = 0, ll lazy_ = 0){ mn = mn_; lazy = lazy_; } } tree[4*len]; void prop(int p, int l, int r){ if (!tree[p].lazy) return; tree[p].mn += tree[p].lazy; if (l != r){ tree[2*p].lazy += tree[p].lazy; tree[2*p+1].lazy += tree[p].lazy; } tree[p].lazy = 0; } void update(int p, int l, int r, int i, int j, int v){ prop(p, l, r); if (i <= l && r <= j) return void(tree[p].lazy += v); int mid = (l+r)/2; if (i <= mid) update(2*p, l, mid, i, j, v); if (j >= mid+1) update(2*p+1, mid+1, r, i, j, v); prop(2*p, l, mid), prop(2*p+1, mid+1, r); tree[p].mn = min(tree[2*p].mn, tree[2*p+1].mn); } ll query(int p, int l, int r, int i, int j){ prop(p, l, r); if (r < i || j < l) return inf; if (i <= l && r <= j) return tree[p].mn; int mid = (l+r)/2; return min(query(2*p, l, mid, i, j), query(2*p+1, mid+1, r, i, j)); } } seg_tree1; bool check(int k){ for (int i = 1; i <= q; i++){ int y1 = rec[i].y1, y2 = rec[i].y2; buck[max(1, y1-k+1)].pb(i); buck[y2+1].pb(-i); } bool ans = false; for (int y = 1; y <= m+1; y++){ int must = (y==1); for (int j = 0; j < buck[y].size(); j++){ int i = abs(buck[y][j]); int x1 = rec[i].x1, x2 = rec[i].x2; if (buck[y][j] > 0) seg_tree1.update(1, 1, n, max(1, x1-k+1), x2, cost[i]); else must = 1, seg_tree1.update(1, 1, n, max(1, x1-k+1), x2, -cost[i]); } buck[y].clear(); if (must && y <= m-k+1) ans |= (seg_tree1.query(1, 1, n, 1, n-k+1) <= bud); } return ans; } int solve1(){ int l = 1, r = min(n, m), ans = 0; while (l <= r){ int mid = (l+r)/2; if (check(mid)) ans = mid, l = mid+1; else r = mid-1; } return ans; } struct{ struct node{ int lazy, mn, pref, suf; int max_pref, max_suf, max_mn, sz; node(int val = 0){ lazy = 0; mn = pref = suf = val; sz = max_mn = max_pref = max_suf = 1; } void join(node &lef, node &rig){ mn = min(lef.mn, rig.mn); max_mn = 0; if (lef.mn == mn) max_mn = max(max_mn, lef.max_mn); if (rig.mn == mn) max_mn = max(max_mn, rig.max_mn); if (lef.suf == mn && rig.pref == mn) max_mn = max(max_mn, lef.max_suf+rig.max_pref); sz = lef.sz+rig.sz; pref = lef.pref; max_pref = lef.max_pref; if (lef.max_pref == lef.sz && rig.pref == lef.suf) max_pref = lef.sz+rig.max_pref; suf = rig.suf; max_suf = rig.max_suf; if (rig.max_suf == rig.sz && lef.suf == rig.pref) max_suf = rig.sz+lef.max_suf; } } tree[4*len]; void build(int p, int l, int r){ if (l == r) return void(tree[p] = node()); int mid = (l+r)/2; build(2*p, l, mid); build(2*p+1, mid+1, r); tree[p].join(tree[2*p], tree[2*p+1]); } void prop(int p, int l, int r){ tree[p].mn += tree[p].lazy; tree[p].pref += tree[p].lazy; tree[p].suf += tree[p].lazy; if (l < r){ tree[2*p].lazy += tree[p].lazy; tree[2*p+1].lazy += tree[p].lazy; } tree[p].lazy = 0; } void update(int p, int l, int r, int i, int j, int v){ prop(p, l, r); if (r < i || j < l) return; if (i <= l && r <= j) return void(tree[p].lazy += v); int mid = (l+r)/2; update(2*p, l, mid, i, j, v); update(2*p+1, mid+1, r, i, j, v); prop(2*p, l, mid), prop(2*p+1, mid+1, r); tree[p].join(tree[2*p], tree[2*p+1]); } /*node query(int p, int l, int r, int i, int j){ tree[p].prop(p, l, r); if (i <= l && r <= j) return tree[p]; int mid = (l+r)/2; if (j <= mid) return query(2*p, l, mid, i, j); if (i >= mid+1) return query(2*p+1, mid+1, r, i, j); node res; res.join(query(2*p, l, mid, i, j), query(2*p+1, mid+1, r, i, j)); return res; }*/ int max_zero(){ prop(1, 1, n); if (tree[1].mn == 0) return tree[1].max_mn; return 0; } } seg_tree2; int solve2(){ for (int i = 1; i <= q; i++){ int y1 = rec[i].y1, y2 = rec[i].y2; buck[y1].pb(i); buck[y2].pb(-i); } seg_tree2.build(1, 1, n); int ans = 0; for (int l = 1, r = 0; l <= m; l++){ while (r <= m && seg_tree2.max_zero() >= r-l+1){ ans = max(ans, r-l+1); r++; for (int j = 0; j < buck[r].size(); j++){ if (buck[r][j] < 0) continue; int i = buck[r][j]; int x1 = rec[i].x1, x2 = rec[i].x2; seg_tree2.update(1, 1, n, x1, x2, +1); } } //printf("for l = %d, first invalid r = %d\n", l, r); for (int j = 0; j < buck[l].size(); j++){ if (buck[l][j] > 0) continue; int i = -buck[l][j]; int x1 = rec[i].x1, x2 = rec[i].x2; seg_tree2.update(1, 1, n, x1, x2, -1); } } return ans; } int main(){ scanf("%d %d %d %d", &n, &m, &bud, &q); for (int i = 1; i <= q; i++) scanf("%d %d %d %d %d", &rec[i].x1, &rec[i].y1, &rec[i].x2, &rec[i].y2, &cost[i]); if (bud > 0) printf("%d\n", solve1()); else printf("%d\n", solve2()); return 0; }

Compilation message (stderr)

pyramid_base.cpp: In function 'bool check(int)':
pyramid_base.cpp:77:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   77 |         for (int j = 0; j < buck[y].size(); j++){
      |                         ~~^~~~~~~~~~~~~~~~
pyramid_base.cpp: In function 'int solve2()':
pyramid_base.cpp:224:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  224 |             for (int j = 0; j < buck[r].size(); j++){
      |                             ~~^~~~~~~~~~~~~~~~
pyramid_base.cpp:234:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  234 |         for (int j = 0; j < buck[l].size(); j++){
      |                         ~~^~~~~~~~~~~~~~~~
pyramid_base.cpp: In function 'int main()':
pyramid_base.cpp:246:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  246 |     scanf("%d %d %d %d", &n, &m, &bud, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pyramid_base.cpp:248:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  248 |         scanf("%d %d %d %d %d", &rec[i].x1, &rec[i].y1, &rec[i].x2, &rec[i].y2, &cost[i]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...
#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...