Problem:
Score : 400 points

Problem Statement

We have N points in a two-dimensional plane.

The coordinates of the i-th point (1 \leq i \leq N) are (x_i,y_i).

Let us consider a rectangle whose sides are parallel to the coordinate axes that contains K or more of the N points in its interior.

Here, points on the sides of the rectangle are considered to be in the interior.

Find the minimum possible area of such a rectangle.

Constraints

2 \leq K \leq N \leq 50

-10^9 \leq x_i,y_i \leq 10^9 (1 \leq i \leq N)

x_i≠x_j (1 \leq i<j \leq N)

y_i≠y_j (1 \leq i<j \leq N)

All input values are integers. (Added at 21:50 JST)

Input

Input is given from Standard Input in the following format:

N K
x_1 y_1
:
x_{N} y_{N}

Output

Print the minimum possible area of a rectangle that satisfies the condition.

Sample Input 1

4 4
1 4
3 3
6 2
8 1

Sample Output 1

21

One rectangle that satisfies the condition with the minimum possible area has the following vertices: (1,1), (8,1), (1,4) and (8,4).

Its area is (8-1) × (4-1) = 21.

Sample Input 2

4 2
0 0
1 1
2 2
3 3

Sample Output 2

1

Sample Input 3

4 3
-1000000000 -1000000000
1000000000 1000000000
-999999999 999999999
999999999 -999999999

Sample Output 3

3999999996000000001

Watch out for integer overflows.

Solution in Rust (1.42.0) (judge verdict: Accepted)

use std::fmt;
use std::fmt::Debug;

#[allow(unused_macros)]
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

#[allow(unused_macros)]
macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}
#[allow(dead_code)]
#[derive(Clone, Debug)]
struct BitVector {
    l: Vec<u64>,
    s: Vec<u64>,
    b: Vec<u16>,
    n_ones: u64,
    size: usize,
    indexed: bool,
}
#[allow(dead_code)]
const BIT_L: usize = 512;
#[allow(dead_code)]
const BIT_S: usize = 16;
#[allow(dead_code)]
impl BitVector {
    fn new(size: usize) -> BitVector {
        let l_len = size / BIT_L + 1;
        let len = (size + BIT_S - 1) / BIT_S;
        BitVector {
            l: vec![0; l_len],
            s: vec![0; len + 1],
            b: vec![0; len],
            n_ones: 0,
            size,
            indexed: true,
        }
    }
    fn build(&mut self) {
        let mut n_ones: u64 = 0;
        for i in 0..self.s.len() {
            let l = (i * BIT_S) / BIT_L;
            if (i * BIT_S) % BIT_L == 0 {
                self.l[l] = n_ones;
            }
            self.s[i] = n_ones - self.l[l];
            if i < self.b.len() {
                n_ones += self.b[i].count_ones() as u64;
            }
        }
        self.n_ones = n_ones;
        self.indexed = true;
    }
    /// self[i]
    fn get(&self, i: usize) -> u16 {
        assert!(i < self.size);
        let (block, offset) = (i / BIT_S, i % BIT_S);
        (self.b[block] >> offset) & 1
    }
    /// self[i] = x
    fn set(&mut self, i: usize, x: u16) {
        assert!(i < self.size);
        assert!(x <= 1);
        let (block, offset) = (i / BIT_S, i % BIT_S);
        self.b[block] = if x == 1 {
            self.b[block] | (1 << offset)
        } else {
            self.b[block] & !(1 << offset)
        };
        self.indexed = false;
    }
    /// Count [0, i)
    fn rank(&self, i: usize) -> u64 {
        assert!(self.indexed);
        assert!(i <= self.size, "{} is out of bounds {}", i, self.size);
        let l = i / BIT_L;
        let s = i / BIT_S;
        let b = if i % BIT_S == 0 {
            0
        } else {
            (self.b[s] << BIT_S - (i % BIT_S)).count_ones()
        };
        self.l[l] + self.s[s] as u64 + b as u64
    }
    /// Count of x in [0, i)
    fn rank_bit(&self, x: u16, i: usize) -> u64 {
        assert!(x <= 1);
        if x == 1 {
            self.rank(i)
        } else {
            i as u64 - self.rank(i)
        }
    }
    /// Count of [0, select(x)) == x
    fn select(&self, b: u16, x: u64) -> usize {
        assert!(self.indexed);
        assert!(b <= 1);
        let negb = |b, c, l| if b == 1 { c } else { l as u64 - c };
        let c = if b == 1 {
            self.n_ones
        } else {
            self.size as u64 - self.n_ones
        };
        if c < x {
            return self.size + 1;
        }
        let mut l = 0;
        let mut r = self.l.len();
        while r - l > 1 {
            let m = (r + l) / 2;
            let c = negb(b, self.l[m], m * BIT_L);
            if c < x {
                l = m;
            } else {
                r = m;
            }
        }
        let li = l;
        let sub = x - negb(b, self.l[li], li * BIT_L);
        let mut l = li * BIT_L / BIT_S;
        let mut r = ((li + 1) * BIT_L / BIT_S).min(self.s.len());
        while r - l > 1 {
            let m = (r + l) / 2;
            let c = negb(b, self.s[m], (m * BIT_S) % BIT_L);
            if c < sub {
                l = m;
            } else {
                r = m;
            }
        }
        let si = l;
        let sub = sub - negb(b, self.s[si], (si * BIT_S) % BIT_L);
        for i in 0..=BIT_S {
            let bs = if i == 0 {
                0
            } else {
                (self.b[si] << BIT_S - i).count_ones()
            };
            let k = negb(b, bs as u64, i);
            if k == sub {
                return si * BIT_S + i;
            }
        }
        unreachable!();
    }
}
#[allow(dead_code)]
impl fmt::Display for BitVector {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut s = String::new();
        for i in 0..self.size {
            s = format!("{}{}", s, (self.b[i / BIT_S] >> i % BIT_S) & 1);
        }
        write!(f, "BitVector:{}", s)
    }
}
#[inline]
#[allow(dead_code)]
fn nth_bit(x: u64, i: usize) -> u16 {
    ((x >> i) & 1) as u16
}
use std::collections::HashMap;
#[allow(dead_code)]
#[derive(Debug, Clone)]
struct Wavelet {
    data: Vec<BitVector>,
    zeros: Vec<usize>,
    l_last: HashMap<u64, usize>,
    max: u64,
    size: usize,
    level: usize,
}
#[allow(dead_code)]
impl Wavelet {
    fn new(v: Vec<u64>) -> Wavelet {
        let size = v.len();
        let max = v.iter().fold(0u64, |x, y| u64::max(x, *y));
        let mut level = 0;
        let mut l = 1;
        while l <= max {
            level += 1;
            l <<= 1;
        }
        let mut data = Vec::with_capacity(level);
        for _ in 0..level {
            data.push(BitVector::new(size))
        }
        let mut res = Wavelet {
            data,
            zeros: vec![0; level],
            l_last: HashMap::new(),
            max,
            size,
            level,
        };
        res.build(v);
        res
    }
    fn build(&mut self, mut v: Vec<u64>) {
        for l in 0..self.level {
            let mut zeros = 0;
            let k = self.level - l - 1;
            for i in 0..self.size {
                let b = nth_bit(v[i], k);
                self.data[l].set(i, b);
                if b == 0 {
                    zeros += 1;
                }
            }
            self.data[l].build();
            self.zeros[l] = zeros;
            v.sort_by(|x, y| nth_bit(*x, k).cmp(&nth_bit(*y, k)));
        }
        self.l_last.insert(v[0], 0);
        for i in 1..v.len() {
            if v[i - 1] != v[i] {
                self.l_last.insert(v[i], i);
            }
        }
    }
    fn pos_bit(&self, l: usize, b: i16, i: usize) -> usize {
        if b == 0 {
            self.data[l].rank_bit(0, i) as usize
        } else {
            self.data[l].rank_bit(1, i) as usize + self.zeros[l]
        }
    }
    fn rev_bit(&self, l: usize, b: u16, i: usize) -> usize {
        if b == 0 {
            self.data[l].select(0, i as u64)
        } else {
            self.data[l].select(1, (i - self.zeros[l]) as u64)
        }
    }
    // self[i]
    fn access(&self, mut i: usize) -> u64 {
        let mut res = 0u64;
        for l in 0..self.level {
            let b = self.data[l].get(i);
            res = (res << 1) + b as u64;
            i = self.pos_bit(l, b as i16, i);
        }
        res
    }
    // Count of x in [0, i)
    fn rank(&self, mut i: usize, x: u64) -> usize {
        if self.l_last.get(&x).is_none() {
            return 0;
        }
        for l in 0..self.level {
            let b = nth_bit(x, self.level - l - 1);
            i = self.pos_bit(l, b as i16, i);
        }
        i - self.l_last.get(&x).unwrap()
    }
    // i == Count of x in [0, res)
    fn select(&self, i: usize, x: u64) -> usize {
        if i == 0 {
            return 0;
        }
        assert!(self.l_last.get(&x).is_some());
        assert!(i <= self.rank(self.size, x));
        let ls = self.l_last.get(&x).unwrap();
        let p = ls + i;
        self.rev_pos(p, x)
    }
    /// last pos and x -> first pos
    fn rev_pos(&self, mut p: usize, x: u64) -> usize {
        for l in (0..self.level).rev() {
            let b = nth_bit(x, self.level - l - 1);
            p = self.rev_bit(l, b, p);
        }
        p
    }
    // [l, r] -> [l0, r0) [l1, r1)
    fn split(&self, level: usize, l: usize, r: usize) -> (usize, usize, usize, usize) {
        let kr = self.data[level].rank(r) as usize;
        let kl = self.data[level].rank(l) as usize;
        let ones = kr - kl;
        let zeros = r - l - ones;
        let l0 = l - kl;
        let r0 = l0 + zeros;
        let l1 = self.zeros[level] + kl;
        let r1 = l1 + ones;
        (l0, r0, l1, r1)
    }
    // i-th number from smaller in [l, r)
    fn quantile_pred(&self, mut l: usize, mut r: usize, mut i: usize) -> (usize, u64) {
        assert!(l < r);
        assert!(i < r - l);
        let mut res = 0;
        for t in 0..self.level {
            let (l0, r0, l1, r1) = self.split(t, l, r);
            res <<= 1;
            if i < r0 - l0 {
                l = l0;
                r = r0;
            } else {
                l = l1;
                r = r1;
                res += 1;
                i -= r0 - l0;
            };
        }
        (l + i, res)
    }
    // i-th smaller [l, r)
    fn quantile(&self, l: usize, r: usize, i: usize) -> u64 {
        self.quantile_pred(l, r, i).1
    }
    // pos of i-th smaller [l, r)
    fn quantile_pos(&self, l: usize, r: usize, i: usize) -> usize {
        let (p, x) = self.quantile_pred(l, r, i);
        self.rev_pos(p + 1, x) - 1
    }
    /// top K increasing order -> smaller to larger
    fn topk(&self, l: usize, r: usize, i: usize) -> Vec<(u64, usize)> {
        use std::cmp::Ordering;
        #[derive(Copy, Clone, Eq, PartialEq)]
        struct State {
            l: usize,
            r: usize,
            level: usize,
            value: u64,
        }
        impl Ord for State {
            fn cmp(&self, other: &Self) -> Ordering {
                (self.r - self.l)
                    .cmp(&(other.r - other.l))
                    .then_with(|| other.level.cmp(&self.level))
                    .then_with(|| other.value.cmp(&self.value))
            }
        }
        impl PartialOrd for State {
            fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
                Some(self.cmp(other))
            }
        }
        let mut q = std::collections::BinaryHeap::new();
        q.push(State {
            l,
            r,
            level: 0,
            value: 0,
        });
        let mut res = vec![];
        while let Some(State { l, r, level, value }) = q.pop() {
            if level >= self.level {
                res.push((value, r - l));
                if res.len() >= i {
                    return res;
                }
                continue;
            }
            let (l0, r0, l1, r1) = self.split(level, l, r);
            if l0 < r0 {
                q.push(State {
                    l: l0,
                    r: r0,
                    level: level + 1,
                    value: value << 1,
                })
            }
            if l1 < r1 {
                q.push(State {
                    l: l1,
                    r: r1,
                    level: level + 1,
                    value: (value << 1) + 1,
                })
            }
        }
        res
    }
    // Sum [l, r)
    fn sum(&self, l: usize, r: usize) -> u64 {
        let top = self.topk(l, r, r - l);
        let mut res = 0;
        for (x, c) in top {
            res += x * c as u64;
        }
        res
    }
    // Intersect [l0, r0) [l1, r1) -> [(x, c0, c1)]
    fn intersect(&self, l0: usize, r0: usize, l1: usize, r1: usize) -> Vec<(u64, usize, usize)> {
        if r0 <= l0 || r1 <= l1 {
            return vec![];
        }
        let mut q = std::collections::VecDeque::new();
        q.push_back((l0, r0, l1, r1, 0, 0));
        let mut res = vec![];
        while let Some((l0, r0, l1, r1, level, value)) = q.pop_front() {
            if level >= self.level {
                res.push((value, r0 - l0, r1 - l1));
                continue;
            }
            let (l00, r00, l01, r01) = self.split(level, l0, r0);
            let (l10, r10, l11, r11) = self.split(level, l1, r1);
            if l00 < r00 && l10 < r10 {
                q.push_back((l00, r00, l10, r10, level + 1, value << 1));
            }
            if l01 < r01 && l11 < r11 {
                q.push_back((l01, r01, l11, r11, level + 1, (value << 1) + 1));
            }
        }
        res
    }
    /// x <= [l, r) < y
    fn range_freq(&self, l: usize, r: usize, x: u64, y: u64) -> usize {
        if y <= x {
            return 0;
        }
        let (xlt, _, _) = self.rank_all(l, r, x);
        let (_, _, yge) = self.rank_all(l, r, y - 1);
        r - l - xlt - yge
    }
    /// [l, r) -> (<x, =x, >x)
    fn rank_all(&self, mut l: usize, mut r: usize, x: u64) -> (usize, usize, usize) {
        if r <= l {
            return (0, 0, 0);
        }
        let mut lt = 0;
        let mut mt = 0;
        for t in 0..self.level {
            let b = nth_bit(x, self.level - t - 1);
            let (l0, r0, l1, r1) = self.split(t, l, r);
            if b == 0 {
                mt += r1 - l1;
                l = l0;
                r = r0;
            } else {
                lt += r0 - l0;
                l = l1;
                r = r1;
            }
        }
        (lt, r - l, mt)
    }
    /// max c in [l, r) if x <= c < y
    fn prev(&self, l: usize, r: usize, x: u64, y: u64) -> Option<u64> {
        self.prev_next(l, r, x, y, true)
    }
    /// min c in [l, r) if x <= c < y
    fn next(&self, l: usize, r: usize, x: u64, y: u64) -> Option<u64> {
        self.prev_next(l, r, x, y, false)
    }
    fn prev_next(&self, l: usize, r: usize, x: u64, mut y: u64, prev: bool) -> Option<u64> {
        if !(x < y && l < r && y > 0 && x <= self.max) {
            return None;
        }
        y -= 1;
        if y > self.max {
            y = self.max;
        }
        let mut s = vec![];
        s.push((l, r, 0, 0, true));
        while let Some((l, r, level, v, t)) = s.pop() {
            if level >= self.level {
                if v >= x {
                    return Some(v);
                }
                continue;
            }
            let b = nth_bit(y, self.level - level - 1);
            let (l0, r0, l1, r1) = self.split(level, l, r);
            // if !t, value goes to lower y
            if prev {
                if l0 < r0 {
                    s.push((l0, r0, level + 1, v << 1, t && b == 0))
                }
                if l1 < r1 {
                    // try from bigger
                    if !t || b == 1 {
                        s.push((l1, r1, level + 1, (v << 1) + 1, t))
                    }
                }
            } else {
                if l1 < r1 {
                    if !t || b == 1 {
                        s.push((l1, r1, level + 1, (v << 1) + 1, t))
                    }
                }
                if l0 < r0 {
                    // try from smaller
                    s.push((l0, r0, level + 1, v << 1, t && b == 0))
                }
            }
        }
        None
    }
}
#[allow(dead_code)]
impl fmt::Display for Wavelet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut s = String::new();
        for i in 0..self.level {
            s = format!("{}{} 0={}\n", s, self.data[i], self.zeros[i]);
        }
        write!(f, "Wavelet:\n{}{:?}\n", s, self.l_last)
    }
}

#[allow(dead_code)]
#[derive(Debug, Clone)]
struct Shrink<T: Clone + Debug + Ord> {
    data: Vec<T>,
}
#[allow(dead_code)]
impl<T: Clone + Debug + Ord> Shrink<T> {
    fn new(vals: &[T]) -> Shrink<T> {
        let set: std::collections::BTreeSet<T> = vals.into_iter().cloned().collect();
        Shrink {
            data: set.iter().cloned().collect(),
        }
    }
    fn shrink(&self, x: T) -> usize {
        lower_bound(&self.data, x)
    }
    fn shrink_upper(&self, x: T) -> usize {
        upper_bound(&self.data, x)
    }
    fn orignal(&self, i: usize) -> T {
        self.data[i].clone()
    }
    fn size(&self) -> usize {
        self.data.len()
    }
}

#[allow(dead_code)]
#[derive(Debug, Clone)]
struct Shrink2<T: Clone + Debug + Ord> {
    data: Vec<(T, T)>,
    data_y: Vec<T>,
}
#[allow(dead_code)]
fn partition_point<T>(data: &[T], ok: &dyn Fn(&T) -> bool) -> usize {
    if !ok(&data[0]) {
        return 0;
    }
    if ok(&data[data.len() - 1]) {
        return data.len();
    }
    let mut l = 0;
    let mut r = data.len();
    while r - l > 1 {
        let m = (r + l) / 2;
        if ok(&data[m]) {
            l = m;
        } else {
            r = m;
        }
    }
    r
}
#[allow(dead_code)]
fn lower_bound<T: Ord>(data: &[T], x: T) -> usize {
    partition_point(data, &|y| y < &x)
}
#[allow(dead_code)]
fn upper_bound<T: Ord>(data: &[T], x: T) -> usize {
    partition_point(data, &|y| y <= &x)
}
#[allow(dead_code)]
impl<T: Clone + Debug + Ord> Shrink2<T> {
    fn new(vals: &[(T, T)]) -> Shrink2<T> {
        let mut x: Vec<(T, T)> = vals.iter().cloned().collect();
        x.sort();
        let ys = x.iter().cloned().map(|(y, _)| y).collect();
        Shrink2 {
            data: x,
            data_y: ys,
        }
    }
    fn shrink(&self, y: T, x: T) -> usize {
        lower_bound(&self.data, (y, x))
    }
    fn shrink_y(&self, y: T) -> usize {
        lower_bound(&self.data_y, y)
    }
    fn shrink_y_upper(&self, y: T) -> usize {
        upper_bound(&self.data_y, y)
    }
    fn orignal(&self, i: usize) -> (T, T) {
        self.data[i].clone()
    }
    fn size(&self) -> usize {
        self.data.len()
    }
}

#[allow(dead_code)]
#[derive(Debug, Clone)]
struct RectQuery<T: Clone + Debug + Ord> {
    wl: Wavelet,
    s2: Shrink2<T>,
    s: Shrink<T>,
    pos: Vec<(T, T)>,
}
#[allow(dead_code)]
impl<T: Clone + Debug + Ord> RectQuery<T> {
    fn new(pos: &[(T, T)]) -> RectQuery<T> {
        let s2 = Shrink2::new(pos);
        let xs: Vec<T> = pos.as_ref().iter().map(|(_, x)| x.clone()).collect();
        let s: Shrink<T> = Shrink::new(&xs[..]);
        let mut w = vec![0; pos.len()];
        for i in 0..s2.data.len() {
            let r = s.shrink(s2.data[i].1.clone()) as u64;
            w[i] = r;
        }
        let wl = Wavelet::new(w);
        RectQuery {
            wl,
            s2,
            s,
            pos: pos.iter().cloned().collect(),
        }
    }
    /// Count in [y0, y1) [x0, x1)
    fn count(&self, y0: T, x0: T, y1: T, x1: T) -> usize {
        let l = self.s2.shrink_y(y0);
        let r = self.s2.shrink_y(y1);
        let x = self.s.shrink(x0) as u64;
        let y = self.s.shrink(x1) as u64;
        self.wl.range_freq(l, r, x, y)
    }
    /// Count in [y0, y1], [x0, x1]
    fn count_in(&self, y0: T, x0: T, y1: T, x1: T) -> usize {
        //println!("{:?}", self.s2);
        //println!("{:?}", self.s);
        //println!("{:?},{:?} {:?},{:?}", y0, x0, y1, x1);
        let l = self.s2.shrink_y(y0);
        let r = self.s2.shrink_y_upper(y1);
        let x = self.s.shrink(x0) as u64;
        let y = self.s.shrink_upper(x1) as u64;
        //println!("=> {}-{} {}=<{}", l, r, x, y);
        self.wl.range_freq(l, r, x, y)
    }
}

fn main() {
    input! {
        n:usize, k:usize,
        xy:[(i64, i64); n]
    };
    if k <= 1 {
        println!("1");
        return;
    }
    let r = RectQuery::new(&xy.clone());
    let mut xs = vec![];
    let mut ys = vec![];
    for (x, y) in xy {
        xs.push(x);
        ys.push(y);
    }
    let xs = Shrink::new(&xs).data;
    let ys = Shrink::new(&ys).data;
    let mut res = 10_000_000_000_000_000_000u64;
    for xi0 in 0..xs.len() {
        let x0 = xs[xi0];
        for xi1 in (xi0 + 1)..xs.len() {
            let x1 = xs[xi1];
            for yi0 in 0..ys.len() {
                let y0 = ys[yi0];
                for yi1 in (yi0 + 1)..ys.len() {
                    let y1 = ys[yi1];
                    let c = r.count_in(x0, y0, x1, y1);
                    let l = (y1 - y0) as u64 * (x1 - x0) as u64;
                    //println!("{} <= {},{} {},{} ({})", c, x0, y0, x1, y1, l);
                    if c >= k {
                        //println!("!");
                        res = res.min(l);
                    }
                }
            }
        }
    }
    println!("{}", res);

    /*
    let mut b = BitVector::new(1000);
    for i in 0..=1000 / 9 {
        b.set(i * 9, 1);
    }
    b.build();
    let mut zeros = 0;
    let mut ones = 0;
    let mut zeroi = vec![0];
    let mut onei = vec![0];

    for i in 0..1000 {
        assert_eq!(b.rank_bit(1, i), ones);
        assert_eq!(b.rank_bit(0, i), zeros);
        if i % 9 == 0 {
            assert_eq!(b.get(i), 1);
            ones += 1;
            onei.push(i + 1);
        } else {
            assert_eq!(b.get(i), 0);
            zeros += 1;
            zeroi.push(i + 1);
        }
    }
    for i in 0..100 {
        assert_eq!(b.select(1, i), onei[i as usize]);
        assert_eq!(b.select(0, i), zeroi[i as usize]);
    }

    let v = vec![1, 2, 3, 1, 2, 2, 4];
    let w = Wavelet::new(v);
    println!("{}", w);
    assert_eq!(w.quantile(1, 5, 3), 3);
    assert_eq!(w.select(1, 3), 3);
    assert_eq!(w.quantile_pos(1, 5, 3), 2);
    assert_eq!(w.topk(0, 7, 3), vec![(2, 3), (1, 2), (3, 1)]);
    assert_eq!(w.topk(2, 6, 3), vec![(2, 2), (1, 1), (3, 1)]);
    assert_eq!(w.sum(2, 6), 8);
    let mut i = w.intersect(0, 3, 2, 7);
    i.sort_by_key(|x| x.0);
    assert_eq!(i, vec![(1, 1, 1), (2, 1, 2), (3, 1, 1)]);
    assert_eq!(w.rank_all(2, 6, 2), (1, 2, 1));
    assert_eq!(w.range_freq(2, 6, 2, 3), 2);
    assert_eq!(w.prev(0, 7, 0, 5), Some(4));
    assert_eq!(w.prev(0, 7, 0, 4), Some(3));
    assert_eq!(w.prev(0, 7, 0, 1), None);
    assert_eq!(w.next(0, 7, 0, 5), Some(1));
    assert_eq!(w.next(0, 7, 2, 5), Some(2));
    assert_eq!(w.next(0, 7, 5, 5), None);

    let pos = vec![(0, 0), (1, 2), (2, 1), (1, 1), (1, 2)];
    let r = RectQuery::new(&pos);
    assert_eq!(r.count(-1, -1, 3, 3), 5);
    assert_eq!(r.count(1, 1, 3, 3), 4);

    let n = 50;
    let m = 1000;
    let mut v: Vec<u64> = vec![];
    let mut pos = vec![vec![0usize]; n];
    let mut cnt = vec![vec![0; m + 1]; n];
    for i in 0..m {
        v.push(i as u64 % n as u64);
        let d: usize = i % n;
        pos[d].push(i as usize + 1);
        for k in 0..n {
            cnt[k][i + 1] = cnt[k][i] + if d == k { 1 } else { 0 };
        }
    }
    let b = Wavelet::new(v.clone());
    for i in 0..m {
        assert_eq!(b.access(i), v[i]);
        for k in 0..n {
            assert_eq!(b.rank(i, k as u64), cnt[k][i])
        }
    }
    for i in 0..m / n {
        for k in 0..n {
            assert_eq!(b.select(i, k as u64), pos[k][i]);
        }
    }
    */
}