sclass RandomizerFromHistogram implements IF0 {
new LPair list;
transient Random randomizer = defaultRandomizer();
*(MultiSet ms) {
long sum = 0;
for (A a : keys(ms)) {
int val = ms.get(a);
if (val == 0) continue;
sum += val;
list.add(pair(a, sum));
}
}
public A get() {
if (empty(list)) null;
long val = randomLong(randomizer, sum());
ret get(val);
}
long sum() { ret empty(list) ? 0 : last(list).b; }
// val must be between 0 and sum()-1
A get(long val) {
int idx = generalizedBinarySearch2(list, p -> cmp((long) p.b, val+1));
if (idx < 0) {
ifdef RandomizerFromHistogram_debug
print("idx1: " + idx);
endifdef
idx = -idx-1;
}
//print("idx: " + idx);
ret assertNotNull(pairA(_get(list, idx)));
}
}