Proofs: Mo's algorithm with updates
These are the human proofs of Mo's algorithm with updates, at full length.
Mo's algorithm with updates makes O(qB + n^2/B + m n^2/B^2) moves full
This proof shows: complexity.
Let be the length of the array, the number of queries, the number of updates, the block size and . The queries are sorted by the key , with and . A group is a maximal run of queries in the sorted order with the same first two key parts . Since , there are at most groups. Each step of a pointer costs one APPLY, ADD or REMOVE, which is .
Lemma 1 (time). The pointer moves at most steps.
Proof. Within one group the values of are non-decreasing, so moves at most steps forward inside it in total. On entering a group, moves from the last of the previous group to the first of this one, at most steps. Summing over the groups gives the bound.
Lemma 2 (left end). The pointer moves steps.
Proof. Between consecutive queries with the same left block, moves less than . Between consecutive queries whose left blocks are , moves at most . The left blocks are non-decreasing along the order, so these sum to at most in total, and the first query costs at most .
Lemma 3 (right end). The pointer moves steps.
Proof. Between consecutive queries in the same group, moves less than . Fix a left block . Among its queries the right block is non-decreasing, so the moves between groups with left block sum to at most , and moving into the first group of costs at most . Over the at most left blocks this is .
Theorem. The total number of steps is . For and it is .
Proof. Add the three lemmas and use . With : , and .
The sort takes comparisons, so the running time is .
Mo's algorithm with updates returns the answer of each query on the array of its time full
This proof shows: correctness, termination.
Let be the original array and the array after the updates , where update sets position to . A query asks for of the multiset . The state of the window is a function of the multiset of values passed to ADD and not yet passed to REMOVE.
Invariant. Between any two steps, (I1) the working array equals ; (I2) for each , , and for each , ; (I3) the state holds the multiset .
At the start, , , every , and the window is empty, so the invariant holds.
Lemma 1 (forward step). If the invariant holds with , then followed by APPLY keeps it.
Proof. By (I2), . Line L12 sets , so by (I1), and stores the old value in , which is (I2) for . If , the multiset of the window loses at line L11 and gains at line L13, and no other position changes, so (I3) holds; otherwise the window multiset is unchanged, and so is the state.
Lemma 2 (backward step). If the invariant holds with , then APPLY followed by keeps it.
Proof. By (I2), , and by (I1) , which differs from only at . Line L12 writes into , so , and stores in , which is (I2) for . The window part is as in Lemma 1.
Lemma 3 (window step). Each single move of or in line L7, as in Mo's algorithm, keeps (I3), and lines L5 to L7 do not change except through APPLY.
Proof. A move adds or removes one position of the window and calls ADD or REMOVE with the current array value, which is the change of the multiset. Lines L4 to L7 of plain Mo's algorithm add before they remove, so throughout and each removed position is in the window.
Theorem. For each query , the recorded answer is , and the algorithm terminates.
Proof. Lines L5 and L6 change by one per step towards , each by Lemma 1 or Lemma 2, so after them and . Line L7 moves to and to by Lemma 3. Then (I3) says the state holds , and line L8 records of it. Every loop moves an integer pointer one step towards a fixed target, so each ends, and there are queries.