Table of Contents

ExplanationImplementation

Official Analysis

Explanation

Let's denote a spot as filled if its value is 00 and empty if its value is 11. The problem boils down to, for each "A" query find the leftmost consecutive segments of 11s and fill it with 00s, and for each "L" query set all values in that range to 11. This can be maintained with a lazy segment tree.

For each segment in our tree, we need to maintain three pieces of information: seg\mathtt{seg} as the maximum amount of consecutive 11s, pref\mathtt{pref} as the maximum prefix of 11s in the segment, and suff\mathtt{suff} as the maximum suffix of 11s in the segment. When merging two segments, make sure to account for overlapping segments; for instance, suff\mathtt{suff} of left segment can merge with pref\mathtt{pref} of right segment. This is because the largest interval can either lay fully inside one of the two segments, or in both when combined.

In order to find the leftmost segment of 11s length of at least vv, we should repeatedly traverse down the left subtree until its seg<v\mathtt{seg} < v. Then, if the segment we are looking for is being overlapped in both left and right segments, then we can just return its start position in the left segment. Otherwise, we traverse down the right subtree.

Implementation

Time Complexity: O(NlogN)\mathcal{O}(N\log N)

C++

#include <bits/stdc++.h>
using namespace std;
struct SegTree {
int size;
struct Item {
int seg, pref, suff, len;
};
vector<int> op;
vector<Item> vals;

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!