Official Analysis

Time Complexity: O(NlogN+Qlog2N)\mathcal O(N\log N + Q\log^2 N)

Let's maintain an array aa, which is sorted by height. To answer a query of type C, we can simply binary search on the endpoints of the query.

Now, we just need to support updates. Let's first binary search for the first position ll such that a[l]ha[l] \geq h. Let r=l+c1r = l + c - 1. We just need to increment the range, [l,r][l, r] by 11 while keeping aa sorted.

However, we cannot just add 11 to all elements in the range, [l,r][l, r] because this might break the sorted order. This happens iff there is some index inside i[l,r]i\in [l, r], such that a[i]=a[r+1]a[i] = a[r + 1]; if we increment the range [l,r][l, r], then a[i]>a[r+1]a[i] > a[r + 1], which is an inversion.

To prevent this error, we find another range [l,r][l', r'], such that a[i]=a[r]a[i] = a[r] for all i[l,r]i\in [l', r']; this can be found with binary search. Since all j<ij < i sastify a[j]<a[i]a[j] < a[i], we can increment [l,l1][l, l' - 1] first. Then, since we need to increment a total of cc elements, we have c(ll)c - (l' - l) elements left. We increment the range [r(c(ll))+1,r][r' - (c - (l' - l)) + 1, r'] by one.

Notice that this doesn't create any inversions because a[r+1]a[r' + 1] is greater than a[r]a[r'] before the update: after the update, the array would be non-decreasing.

Updates and queries can be handled with a lazy segment tree, but a binary indexed tree would suffice since we only need point queries.

C++

#include <bits/stdc++.h>
using namespace std;
#define N 100000
int n, q, a[N], bit[N];
void add(int l, int r, int x) { // add x to [l, r]
if (r < l) return;
for (; l < n; l |= l + 1) bit[l] += x;

Join the USACO Forum!

Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!