Definition ijs (n: nat): list (nat * nat) :=
  concat (map (fun j => map (fun i => (i, j)) (nats 0 j)) (nats 0 n)).

(* Specifications: *)
Lemma In_ijs n i j: lt i j -> lt j n -> List.In (i, j) (ijs n).
Lemma In_ijs_inv n i j: List.In (i, j) (ijs n) -> (i < j < n)%nat.
Lemma expand_sumOver_ijs n (f: nat * nat -> R): RsumOver (ijs n) f = RsumOver (nats 0 n) (fun j => RsumOver (nats 0 j) (fun i => f (i, j))).
Lemma sumOver_ijs_bound n: RsumOver (ijs n) (fun ij => 2 / INR (S (snd ij - fst ij))) <= 2 * INR n * INR (S (log2ceil n)).
Theorem Umonoid_expec_qs_bounded_by_sumOver_ijs l: IndexSeq 0 l -> @monoid_expec U.monoid length _ (qs (@U.cmp ee ol) U.pick l) <= RsumOver (ijs (length l)) (fun ij => 2 / INR (S (snd ij - fst ij))).
Theorem qs_expec_cost: expec cost (NDP.qs ee ol) <= 2 * INR (length ol) * INR (S (log2ceil (length ol))).