Problem:
Score : 600 points

Problem Statement

You are given an integer sequence A of length N and an integer K.
You will perform the following operation on this sequence Q times:

Choose a contiguous subsequence of length K, then remove the smallest element among the K elements contained in the chosen subsequence (if there are multiple such elements, choose one of them as you like).

Let X and Y be the values of the largest and smallest element removed in the Q operations. You would like X-Y to be as small as possible.
Find the smallest possible value of X-Y when the Q operations are performed optimally.

Constraints

1 \leq N \leq 2000

1 \leq K \leq N

1 \leq Q \leq N-K+1

1 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K Q
A_1 A_2 ... A_N

Output

Print the smallest possible value of X-Y.

Sample Input 1

5 3 2
4 3 1 5 2

Sample Output 1

1

In the first operation, whichever contiguous subsequence of length 3 we choose, the minimum element in it is 1.
Thus, the first operation removes A_3=1 and now we have A=(4,3,5,2).
In the second operation, it is optimal to choose (A_2,A_3,A_4)=(3,5,2) as the contiguous subsequence of length 3 and remove A_4=2.
In this case, the largest element removed is 2, and the smallest is 1, so their difference is 2-1=1.

Sample Input 2

10 1 6
1 1 2 3 5 8 13 21 34 55

Sample Output 2

7

Sample Input 3

11 7 5
24979445 861648772 623690081 433933447 476190629 262703497 211047202 971407775 628894325 731963982 822804784

Sample Output 3

451211184

Solution in Rust (1.15.1) (judge verdict: Wrong Answer)

use std::io::*;
use std::str::FromStr;
use std::collections::BTreeMap;

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn remove_value(open: &mut BTreeMap<i32, usize>, v: i32, cnt: &mut usize) {
    let mut rm = false;
    if let Some(counter) = open.get_mut(&v) {
        *cnt -= 1;
        *counter -= 1;
        if *counter == 0 {
            rm = true;
        }
    }
    if rm {
        open.remove(&v);
    }
}

fn solve(seq: &Vec<i32>, k: usize, q: usize, min_value: i32, max_value: i32) -> i32 {
    let n = seq.len();
    let mut open = BTreeMap::<i32, usize>::new();
    let mut l = 0;
    let mut cnt = 0;
    let mut ans_seq = vec![];
    let mut small_value = 0;
    let mut large_value = 0;
    for i in 0..n {
        cnt += 1;
        if seq[i] < min_value {
            small_value += 1;
        } else if max_value < seq[i] {
            large_value += 1;
        } else {
            *open.entry(seq[i]).or_insert(0) += 1;
        }
        while cnt > k {
            let v = seq[l];
            l += 1;
            if v < min_value {
                small_value -= 1;
                cnt -= 1;
            } else if max_value < v {
                large_value -= 1;
                cnt -= 1;
            } else {
                remove_value(&mut open, v, &mut cnt);
            }
        }
        if cnt == k && small_value == 0 && large_value != k {
            let &v = open.iter().next().unwrap().0;
            ans_seq.push(v);
            remove_value(&mut open, v, &mut cnt);
            if ans_seq.len() == q {
                break;
            }
        }
    }
    if ans_seq.len() < q {
        return max_value + 100;
    }
    ans_seq.sort();
    let ret = ans_seq[q - 1] - ans_seq[0];
    // println!("{:?}", ans_seq);
    assert!(ret <= max_value - min_value);
    ret
}

fn main() {
    let n = read::<usize>();
    let k = read::<usize>();
    let q = read::<usize>();
    let mut seq = vec![0; n];
    for i in 0..n {
        seq[i] = read::<i32>();
    }
    let mut sort_seq = seq.clone();
    sort_seq.sort();
    let mut best_values = vec![1e+9 as i32; n];
    for i in 0..n {
        if i + q - 1 < n {
            best_values[i] = sort_seq[i + q - 1] - sort_seq[i];
        }
    }
    let mut ans = 1e+9 as i32;
    for i in 0..n {
        if i != 0 && sort_seq[i - 1] == sort_seq[i] {
            continue;
        }
        let min_value = sort_seq[i];
        let mut left = best_values[i];
        let mut right = ans;
        while right - left > 1 {
            let mid = (left + right) / 2;
            let v = solve(&seq, k, q, min_value, min_value + mid);
            // println!("{} {} {} {}", left, right, mid, v);
            if v <= mid {
                right = v;
            } else {
                left = mid;
            }
        }
        ans = right;
        if right != 0 {
            ans = std::cmp::min(ans, solve(&seq, k, q, min_value, min_value + right - 1));
        }
    }
    println!("{}", ans);
}