Run the binary searches of queries simultaneously, so that the expensive “apply the first operations” step is done once per round instead of once per query.

The problem it solves

“There are operations applied in order. For each of queries, find the earliest moment at which its condition becomes true.”

Binary searching each query independently costs rebuilds of the structure — far too slow when a rebuild is or worse.

The technique

Each query keeps its own interval . In each round:

  1. Group the queries by their midpoint .
  2. Sweep the operations from 1 to once, and whenever the operation index equals some group’s midpoint, evaluate all queries in that group against the current structure.
  3. Narrow each query’s interval based on its result.

After rounds every interval collapses.

vector<int> lo(q, 0), hi(q, m);
while (true) {
    vector<vector<int>> byMid(m + 1);
    bool anyLeft = false;
    for (int i = 0; i < q; i++)
        if (lo[i] < hi[i]) { byMid[(lo[i] + hi[i]) / 2].push_back(i); anyLeft = true; }
    if (!anyLeft) break;
 
    reset();                                        // fresh structure
    for (int t = 1; t <= m; t++) {
        apply(t);                                   // the t-th operation
        for (int i : byMid[t]) {
            if (check(i)) hi[i] = t; else lo[i] = t + 1;
        }
    }
}

Complexity: rounds, each .

Worked example: “when does this pair become connected?”

Edges are added one at a time; for each query pair , find the first edge index after which they are connected.

  • apply(t)dsu.unite(edges[t]), ;
  • check(i)dsu.same(u_i, v_i), ;
  • reset() — a fresh DSU, .

Total . Independently binary searching would be .

This is the standard solution to “minimum bottleneck edge on a path” for many queries (also solvable with MST + binary lifting, but parallel binary search generalises further).

More examples

Problemapplycheck
First moment and are connectedunion an edgeDSU same
First moment a region receives itemsrange add on a BITprefix query
-th smallest with insertionsinsert into a BITcount mid
First moment a subgraph becomes bipartiteunion with parityconsistency check
Minimum capacity for all flows to succeedadd an edgemax-flow value
First round in which a player is eliminatedapply a roundevaluate a condition

Parallel binary search vs the alternatives

TechniqueHandlesCost
Parallel binary search”when does the answer flip” for many queries rebuilds
Segment tree on timequeries at arbitrary times with add and remove per operation
CDQmulti-dimensional dominance
Persistent structuresonline historical queries per query
Independent binary searchesfew queries

The distinguishing feature: parallel binary search needs only an incrementally buildable structure (add-only), not a rollback-able or persistent one — which makes plain DSU sufficient where offline dynamic connectivity would need rollback.

Requirements

  1. Each query’s predicate must be monotone in time: once true, always true.
  2. The structure must support applying operations in order from a fresh state.
  3. All queries must be known up front (this is an offline technique).

If the predicate is not monotone, the technique does not apply — verify this before writing it.

Implementation notes

  • Reset the structure completely each round, or use rollbacks; leftover state is the usual bug.
  • Bucketing queries by midpoint is what makes one sweep serve all of them — do not sort queries by their own /.
  • Handle “never becomes true” by initialising and checking for that sentinel at the end.
  • The rounds are independent, so this parallelises trivially across threads if that is ever useful.

See also: Binary Search · Offline Query Processing · Dynamic Connectivity