Two families of “over all subarrays” problems. Both rest on the fact that the aggregate changes few times as the left end moves.

Few distinct values per right end

Fix the right end and move leftwards. Then changes times, because each change at least halves it. and change times, because each change sets or clears a bit. LCM changes times while it stays below a bound . (Min and max do not have this property; use a monotonic stack for those.)

Keep the list of (value, number of left ends) runs for the current and extend it by :

// runs: (value of op(a[l..r]), count of l giving it), most recent first
template<class Op> map<ll, ll> countByValue(const vector<ll>& a, Op op) {
    map<ll, ll> total;
    vector<pair<ll, ll>> cur;
    for (ll x : a) {
        vector<pair<ll, ll>> nxt = {{x, 1}};
        for (auto [v, c] : cur) {
            ll w = op(v, x);
            if (w == nxt.back().first) nxt.back().second += c; else nxt.push_back({w, c});
        }
        cur = move(nxt);
        for (auto [v, c] : cur) total[v] += c;
    }
    return total;
}

That’s operations (gcd costs another in theory, but each chain of gcds telescopes to total per position).

Uses:

  • count subarrays with gcd (or OR, AND) equal to , for many queries ;
  • number of distinct ORs over all subarrays;
  • sum over all subarrays of gcd times length: store the leftmost of each run;
  • shortest or longest subarray with gcd ending at ;
  • “is there a subarray with gcd / OR ”, and minimum length;
  • range queries “how many subarrays inside have gcd ”: sweep , and runs become range-add events on a BIT indexed by .

Two pointers with gcd: gcd isn’t invertible, so the window needs a two-stack queue or a sparse table. With a sparse table, is for a static array, since overlapping ranges are harmless for gcd.

Mex over subarrays

The mex of a set is the smallest non-negative integer not in it.

Mex of the whole array with updates: keep cnt[v] for and a segment tree (or a set of absent values) over that finds the first with cnt[v] == 0. Values larger than never matter, since the mex is at most .

Mex of a query range, offline: sweep and maintain last[v] = last position of in a segment tree over values storing the minimum of last. The mex of is the first with last[v] < l, found by descending. Make it persistent over to answer online. .

Which values are mexes of some subarray (CF 1436E): is the mex of some subarray iff some maximal segment avoiding (between consecutive occurrences of , or before the first or after the last) contains all of . Sweep with the same “min of last positions over ” tree, and check each gap when its closing occurrence of arrives. .

Counting and summing mex over all subarrays:

  • Fix the left end and track = mex of , which is non-decreasing in . Compute for in one pass.
  • Moving to deletes : for before the next occurrence of , the new value is . Since is monotone, that’s a range assign on a suffix of that interval, found by binary search on the segment tree. Summing after each step gives the sum of mexes over all subarrays in .
  • Alternatively, . For a permutation each count is a rectangle determined by the span of the positions of , so the whole sum is .

Mex of a set as a game value: Grundy numbers are mexes; see Sprague-Grundy.

Mex with permutations: in a permutation of , the mex of a subarray is iff the subarray contains positions of and not the position of . Fixing gives a rectangle of valid , counted in , so all-subarray statistics on permutations are .