Submission #776192

#TimeUsernameProblemLanguageResultExecution timeMemory
776192PanosPaskGrowing Trees (BOI11_grow)C++14
100 / 100
148 ms6584 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; struct SegTree { const ll NO_OP = 0; const ll NEUTRAL = LLONG_MAX; int size; int n; vector<ll> tree; vector<ll> operations; void build(vector<int>& a, int x, int lx, int rx) { if (lx == rx - 1) { if (lx < a.size()) tree[x] = a[lx]; else tree[x] = NEUTRAL; return; } int mid = (lx + rx) / 2; build(a, 2 * x + 1, lx, mid); build(a, 2 * x + 2, mid, rx); tree[x] = max(tree[2 * x + 1], tree[2 * x + 2]); } void init(int n, vector<int>& a) { size = 1; this->n = n; while (size < n) size *= 2; tree.resize(2 * size); operations.assign(2 * size, NO_OP); build(a, 0, 0, size); } void propagate(int x) { tree[2 * x + 1] += operations[x]; tree[2 * x + 2] += operations[x]; operations[2 * x + 1] += operations[x]; operations[2 * x + 2] += operations[x]; operations[x] = NO_OP; } void modify(int l, int r, int v, int x, int lx, int rx) { if (lx >= r || l >= rx) { return; } else if (l <= lx && rx <= r) { tree[x] += v; operations[x] += v; return; } propagate(x); int mid = (lx + rx) / 2; modify(l, r, v, 2 * x + 1, lx, mid); modify(l, r, v, 2 * x + 2, mid, rx); tree[x] = max(tree[2 * x + + 1], tree[2 * x + 2]); } ll get(int i, int x, int lx, int rx) { if (lx == rx - 1) { return tree[x]; } propagate(x); int mid = (lx + rx) / 2; if (i < mid) return get(i, 2 * x + 1, lx, mid); else return get(i, 2 * x + 2, mid, rx); } // Returns the first element more than or equal to v int lower_bound(ll v, int x, int lx, int rx) { if (tree[x] < v) return -1; else if (lx == rx - 1) return lx; propagate(x); int mid = (lx + rx) / 2; int res = lower_bound(v, 2 * x + 1, lx, mid); if (res == -1) res = lower_bound(v, 2 * x + 2, mid, rx); return res; } // Count elements with value in [minv, maxv] int count_between(int minv, int maxv) { int r = lower_bound(maxv + 1, 0, 0, size); int l = lower_bound(minv, 0, 0, size); return r - l; } // Increment the shortest num elements with height over minv void increment(int minv, int num) { // First element to be incremented int l = lower_bound(minv, 0, 0, size); if (l >= n) return; // Last element to be incremented int r = l + num - 1; if (r >= n) { modify(l, n, 1, 0, 0, size); return; } ll v = get(r, 0, 0, size); // First element equal to a[r] int first = lower_bound(v, 0, 0, size); // First element equal to (a[r] + 1) int last = lower_bound(v + 1, 0, 0, size); // The range [l.. f) can be freely incremented modify(l, first, 1, 0, 0, size); int left_to_inc = num - (first - l); // Increment the last elements equal to r modify(last - left_to_inc, last, 1, 0, 0, size); return; } }; int n, m; vector<int> a; SegTree st; int main(void) { scanf("%d %d", &n, &m); a.resize(n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); sort(a.begin(), a.end()); st.init(n, a); while (m--) { char op; scanf(" %c", &op); if (op == 'F') { int c, h; scanf("%d %d", &c, &h); st.increment(h, c); } else { int l, r; scanf("%d %d", &l, &r); printf("%d\n", st.count_between(l, r)); } } return 0; }

Compilation message (stderr)

grow.cpp: In member function 'void SegTree::build(std::vector<int>&, int, int, int)':
grow.cpp:18:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   18 |             if (lx < a.size())
      |                 ~~~^~~~~~~~~~
grow.cpp: In function 'int main()':
grow.cpp:149:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  149 |     scanf("%d %d", &n, &m);
      |     ~~~~~^~~~~~~~~~~~~~~~~
grow.cpp:153:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  153 |         scanf("%d", &a[i]);
      |         ~~~~~^~~~~~~~~~~~~
grow.cpp:159:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  159 |         scanf(" %c", &op);
      |         ~~~~~^~~~~~~~~~~~
grow.cpp:163:18: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  163 |             scanf("%d %d", &c, &h);
      |             ~~~~~^~~~~~~~~~~~~~~~~
grow.cpp:169:18: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  169 |             scanf("%d %d", &l, &r);
      |             ~~~~~^~~~~~~~~~~~~~~~~
#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...