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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <cassert>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <memory.h>
#include <map>
#include <set>
#include <queue>
#include <list>
#include <sstream>
#include <cstring>
using namespace std ;

#define ft first
#define sd second
#define pb push_back
#define all(x) x.begin(),x.end()

#define ll long long int
#define vi vector<int>
#define vii vector<pair<int,int> >
#define pii pair<int,int>
#define plii pair<pair<ll, int>, int>
#define piii pair<pii, int>
#define viii vector<pair<pii, int> >
#define vl vector<ll>
#define vll vector<pair<ll,ll> >
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define mp make_pair
#define ms(x, v) memset(x, v, sizeof x)

#define sc1(x) scanf("%d",&x)
#define sc2(x,y) scanf("%d%d",&x,&y)
#define sc3(x,y,z) scanf("%d%d%d",&x,&y,&z)

#define scll1(x) scanf("%lld",&x)
#define scll2(x,y) scanf("%lld%lld",&x,&y)
#define scll3(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)

#define pr1(x) printf("%d\n",x)
#define pr2(x,y) printf("%d %d\n",x,y)
#define pr3(x,y,z) printf("%d %d %d\n",x,y,z)

#define prll1(x) printf("%lld\n",x)
#define prll2(x,y) printf("%lld %lld\n",x,y)
#define prll3(x,y,z) printf("%lld %lld %lld\n",x,y,z)

#define pr_vec(v) for(int i=0;i<v.size();i++) cout << v[i] << " " ;

#define f_in(st) freopen(st,"r",stdin)
#define f_out(st) freopen(st,"w",stdout)

#define fr(i, a, b) for(i=a; i<=b; i++)
#define fb(i, a, b) for(i=a; i>=b; i--)
#define ASST(x, l, r) assert( x <= r && x >= l )

const int mod = 1e9 + 7;

int ADD(int a, int b, int m = mod) {
    int s = a;
    s += b;
    if( s >= m )
      s -= m;
    return s;
}

int MUL(int a, int b, int m = mod) {
    return (1LL * a * b % m);
}

int power(int a, int b, int m = mod) {
    int res = 1;
    while( b ) {
        if( b & 1 ) {
            res = 1LL * res * a % m;
        }
        a = 1LL * a * a % m;
        b /= 2;
    }
    return res;
}

ll nC2(ll x) {
    return ( x * ( x - 1 ) / 2 );
}

class dsu{
   public :
   int n, max_component, ans, k;
   vector<int> P , R , S;
   dsu(int n, int k){
       this->n = n ;
       this->k = k;
       P.resize(n+1) ;
       R.resize(n+1) ;
       S.resize(n+1) ;
       for(int i=1;i<=n;i++){
           R[i] = 0 ;
           P[i] = i ;
           S[i] = 1 ;
           ans += max(0, S[i] - k + 1);
       }
       max_component = 1 ;
       ans = 0;
   }
   int find(int x){
       if(x != P[x]){
           P[x] = find(P[x]) ;
       }
       return P[x] ;
   }
   bool add_edge(int x,int y){
       int rx , ry ;
       rx = find(x) ;
       ry = find(y) ;
       if(rx != ry){
           if(R[rx] < R[ry]){
               P[rx] = ry ;
               ans -= max(0, S[ry] - k + 1);
               S[ry] += S[rx] ;
               ans += max(0, S[ry] - k + 1);
               max_component = max(max_component,S[ry]) ;
           }else{
               P[ry] = rx ;
               ans -= max(0, S[rx] - k + 1);
               S[rx] += S[ry] ;
               ans += max(0, S[rx] - k + 1);
               max_component = max(max_component,S[rx]) ;
           }
           if(R[rx] == R[ry]){
               R[rx] ++ ;
           }
           return true ;
       }
       return false ;
   }

} ;

const int maxn = 1e5 + 10;
bool vis[maxn];
int main() {
    int n, k, q;
    cin >> n >> k >> q;
    int i; 
    vii A; fr(i, 1, n) {
        int x; cin >> x;
        A.pb(mp(x, i));
    }
    dsu ds(n, k);
    sort(all(A)); reverse(all(A));
    i = 0;
    vii Z;
    while( i < n ) {
        int x = A[i].ft;
        while( i < n && x == A[i].ft ) {
            vis[A[i].sd] = 1;
            if(vis[A[i].sd - 1]) ds.add_edge(A[i].sd - 1, A[i].sd);
            if(vis[A[i].sd + 1]) ds.add_edge(A[i].sd + 1, A[i].sd);
            i ++;
        }
        Z.pb(mp(x, ds.ans));
    }
    i = 0; 
    int j = 0, fans = 2 * 1e9 + 10;
    while( i < Z.size() ) {
        if(Z[i].sd >= q) fans = 0;
        while( j < Z.size() && Z[j].sd - Z[i].sd < q ) j ++;
        if( j < Z.size() && i + 1 < Z.size()) fans = min(fans, Z[i+1].ft - Z[j].ft);
        i ++;
    }
    cout << fans << "\n";
    return 0;
}