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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
class Program{
	const int mod=1000000007;
	const long o=1;
	static Bit bit;
	static void Main(){
		Sc sc=new Sc();
		int[] s=sc.Ia,a=sc.Ia;
		long ans=0;
		int[][] h=new int[s[0]][];
		for(int i = 0;i<s[0];i++) {h[i]=new int[]{a[i],i+1};}
		Array.Sort(h,(u,v)=>u[0]-v[0]);
		bit=new Bit(s[0]);
		var hs=new Dictionary<string,int>();
		bit.Ud(h[0][1],1);
		ans=h[s[2]-1][0]-h[0][0];
		for(int i = 1;i<=s[0]-s[2];i++) {
			if(h[i+s[2]-1][0]-h[i][0]<ans){
				int p=0;
				for(int j = i;;j++) {
					long q=bit.Get(h[j][1]);
					int l=Fu(0,h[j][1],q)+(q==0?0:1),r=Fu(h[j][1],s[0]+1,q+1)-1;
					string t=l+" "+r;
					
					if(r-l-(hs.ContainsKey(t)?hs[t]:0)+1>=s[1]){
						if(j-i-p+1==s[2]){
							ans=h[i+s[2]-1+p][0]-h[i][0];
							break;
						}
					}
					else{
						p++;
						if(i+s[2]-1+p>=s[0]){break;}
						else if(h[i+s[2]-1+p][0]-h[i][0]>=ans){break;}
					}
					if(hs.ContainsKey(t)){hs[t]++;}
					else{hs.Add(t,1);}
				}
				hs.Clear();
			}
			bit.Ud(h[i][1],1);
		}
		Console.WriteLine("{0}",ans);
	}
	static int Fu(int lb,int ub,long q){
		int mid=0;
		while(ub-lb>1){
			mid=(ub+lb)/2;
			if(bit.Get(mid)>=q){ub=mid;}
			else{lb=mid;}
		}
		return ub;
	}
}
public class Bit{
	private int n;
	private long[] bit;
	public Bit(int n){
		this.n=n;
		bit=new long[n+1];
	}
	public void Ud(int a,long p){while(a<=n){bit[a]+=p;a+=a&-a;}}
	public long Get(int n){
		long a=0;
		while(n>0){a+=bit[n];n-=n&-n;}
		return a;
	}
	public long Get2(int m,int n){
		long a=0,b=0;
		while(n>m){a+=bit[n];n-=n&-n;}
		if(n==m){return a;}
		while(n!=m){b+=bit[m];m-=m&-m;}
		return a-b;
	}
	public void Clear(){bit=new long[n+1];}
}

class Sc{
	public int I{get{return int.Parse(Console.ReadLine());}}
	public long L{get{return long.Parse(Console.ReadLine());}}
	public double D{get{return double.Parse(Console.ReadLine());}}
	public string S{get{return Console.ReadLine();}}
	public int[] Ia{get{return Array.ConvertAll(Console.ReadLine().Split(),int.Parse);}}
	public long[] La{get{return Array.ConvertAll(Console.ReadLine().Split(),long.Parse);}}
	public double[] Da{get{return Array.ConvertAll(Console.ReadLine().Split(),double.Parse);}}
	public string[] Sa{get{return Console.ReadLine().Split();}}
}