Problem:
Score : 400 points

Problem Statement

You are given N items.

The value of the i-th item (1 \leq i \leq N) is v_i.

Your have to select at least A and at most B of these items.

Under this condition, find the maximum possible arithmetic mean of the values of selected items.

Additionally, find the number of ways to select items so that the mean of the values of selected items is maximized.

Constraints

1 \leq N \leq 50

1 \leq A,B \leq N

1 \leq v_i \leq 10^{15}

Each v_i is an integer.

Input

The input is given from Standard Input in the following format:

N A B
v_1
v_2
...
v_N

Output

Print two lines.

The first line should contain the maximum possible arithmetic mean of the values of selected items. The output should be considered correct if the absolute or relative error is at most 10^{-6}.

The second line should contain the number of ways to select items so that the mean of the values of selected items is maximized.

Sample Input 1

5 2 2
1 2 3 4 5

Sample Output 1

4.500000
1

The mean of the values of selected items will be maximized when selecting the fourth and fifth items. Hence, the first line of the output should contain 4.5.

There is no other way to select items so that the mean of the values will be 4.5, and thus the second line of the output should contain 1.

Sample Input 2

4 2 3
10 20 10 10

Sample Output 2

15.000000
3

There can be multiple ways to select items so that the mean of the values will be maximized.

Sample Input 3

5 1 5
1000000000000000 999999999999999 999999999999998 999999999999997 999999999999996

Sample Output 3

1000000000000000.000000
1

Solution in C (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <stdlib.h>
#include <stdbool.h>
#define MOD 1000000007
#define END printf("\n");return 0;
void input_array(long how_data,long *data);
void input_array2(int first , int second , int data[][2]);
int get_random(int min, int max);
long factorial(long n);
int fibonacci(int n);
int qsort_09(const int *sys1 , const int *sys2);
long qsort_90(const int *sys1 , const int *sys2);
int sel_max(int a , int b);
int sel_min(int a , int b);
int array_max(int how_data,int *data);
int array_min(int how_data,int *data);
int can_DP(int how_data,int *data,int how_can,bool *can);
int array_sum(int how_data,int *data);
int Leven_dist(char *now , char *target);
void prime_fact(int target, int *data);
int get_digit(int target);
long ncr(long n , long r);
int loop1,loop2,loop3,loop4,loop5,i_temp;
char c_temp;

int main(void){
    int n,a,b;
    scanf("%d %d %d",&n,&a,&b);
    long data[n];
    input_array(n,data);
    qsort(data,n,sizeof(long),(int (*)(const void *,const void *))qsort_90);
    //大きい順にsort
    //上位A個の平均が最大の平均とできる
    //A+1個めが、A個目より小さかったら組み合わせ数は「1」で確定
    long double ave_max=0.00;
    for(loop1=0;loop1<a;loop1++){
        ave_max+=data[loop1];
    }
    ave_max/=a;
    printf("%.9Lf\n",ave_max);
    if(a!=n && data[a-1]>data[a]){
        printf("1\n");
        return 0;
    }
    //A個めと同じ大きさのデータが複数(といってもBまでが限界)あるとめんどい
    if(data[0]!=data[a-1]){//この場合はA個確定
        //data[a-1]と同じデータがいくつある？
        long how_a_sub_1_n=0;
        long how_a_sub_1_r=0;
        for(loop1=0;loop1<n;loop1++){
            if(data[loop1]==data[a-1]){
                how_a_sub_1_n++;
                if(loop1<a){
                    how_a_sub_1_r++;
                }
            }
        }
        printf("%ld\n",ncr(how_a_sub_1_n,how_a_sub_1_r));
        return 0;
    }else if(data[0]==data[a-1]){
        //同値であれば、Bまでいける
        long ans=0;
        int how_douti=0;
        for(loop1=0;loop1<n;loop1++){
            if(data[0]==data[loop1]){
                how_douti++;
            }
        }
        //printf("%d\n",how_douti);
        for(loop1=a;loop1<=(sel_min(b,how_douti));loop1++){
            ans+=(ncr(how_douti,loop1));
            //printf("%d c %d = %ld\n",how_douti,loop1,ans);
        }
        printf("%ld\n",ans);
        return 0;
    }
    
}


//how_data個の配列data[]に標準入力
//input_array(how_data,data);
void input_array(long how_data,long *data){
    long loop;
    for(loop=0;loop<how_data;loop++){
        scanf("%ld",&data[loop]);
    }
    return ;
}

void input_array2(int first,int second,int data[][2]){
    int loopA,loopB;
    for(loopA=0;loopA<first;loopA++){
        for(loopB=0;loopB<second;loopB++){
            scanf("%d",&data[loopA][loopB]);
        }
    }
    return ;
}

int get_random(int min, int max){   //指定の範囲から乱数を1つ返すやつ
    //srand((unsigned int)time(0));   //現在時刻で疑似乱数初期化
    rand();rand();rand();rand();    //乱数を空打ち
    return (rand()%(max+1-min))+min;
}


long factorial(long n){//n!のMOD10^9+7を返すやつ
    unsigned long long int ret=1;
    for(int i=1;i<=n;i++)ret=(ret*i)%1000000007;
    return (long)ret;
}

int qsort_09(const int *sys1 , const int *sys2){ //小さいのが上にくるやつ
    //qsort(data,how_data,sizeof(int),(int (*)(const void *,const void *))qsort_09);
    if(*sys1<*sys2){
        return -1;
    }else if(*sys1==*sys2){
        return 0;
    }else{
        return 1;
    }
}

long qsort_90(const int *sys1 , const int *sys2){ //大きいのが上にくるやつ
    //qsort(data,how_data,sizeof(int),(int (*)(const void *,const void *))qsort_90);
    if(*sys1<*sys2){
        return 1;
    }else if(*sys1==*sys2){
        return 0;
    }else{
        return -1;
    }
}

int fibonacci(int n){
    switch(n){
        case 0:return 0;
        case 1:return 1;
        default :return fibonacci(n-1)+fibonacci(n-2);
    }
}

int sel_max(int a,int b){
    if(a>b)return a;
    return b;
}

int sel_min(int a,int b){
    if(a>b)return b;
    return a;
}

int can_DP(int how_data,int *data,int how_can,bool *can){//Typical DP Contest A
    //data内で組み合わせられる和をcanに0 or 1で入れる
    //返り値はパターン数
    int loopA,loopB;
    int ret=0;
    for(loopA=0;loopA<how_can;loopA++){//初期化
        can[loopA]=0;
    }
    can[0]=1;//絶対にありえる
    for(loopA=0;loopA<how_data;loopA++){
        for(loopB=how_can-1;loopB>=0;loopB--){
            if(can[loopB]==1 && loopB+data[loopA]<how_can){
                can[loopB+data[loopA]]=1;
            }
        }
    }
    for(loopA=0;loopA<how_can;loopA++){
        if(can[loopA]==1){
            ret++;
        }
    }
    return ret;
}
int array_max(int how_data,int *data){
    int loop;
    int ret=data[0];
    for(loop=0;loop<how_data;loop++){
        if(ret<data[loop])ret=data[loop];
    }
    return ret;
}
int array_min(int how_data,int *data){
    int loop;
    int ret=data[0];
    for(loop=0;loop<how_data;loop++){
        if(ret>data[loop])ret=data[loop];
    }
    return ret;
}
int array_sum(int how_data,int *data){
    int ret=0;
    int loop;
    for(loop=0;loop<how_data;loop++){
        ret+=data[loop];
    }
    return ret;
}
int Leven_dist(char *now , char *target){
    int loopA,loopB;
    //レーベンシュタイン距離を求める
    // 参考文献
    // http://nw.tsuda.ac.jp/class/algoB/c13.html  (アルゴリズム理解)
    // http://d.hatena.ne.jp/ohnishiakira/20090809/1249845529  (実装)
    int len_now=strlen(now)+1;
    int len_target=strlen(target)+1;
    int d[len_now][len_target]; //計算用
    for(loopA=0;loopA<len_now;loopA++) d[loopA][0]=loopA;
    for(loopA=0;loopA<len_target;loopA++) d[0][loopA]=loopA;
    for(loopA=1;loopA<len_now;loopA++){
        for(loopB=1;loopB<len_target;loopB++){
            int cost=(now[loopA-1]==target[loopB-1] ? 0:1);
            d[loopA][loopB]=sel_min(sel_min(d[loopA-1][loopB]+1,d[loopA][loopB-1]+1),d[loopA-1][loopB-1]+cost);
        }
    }
    return d[len_now-1][len_target-1];
}
void prime_fact(int target, int *data){
    int loopB=0;
    int loopA=2;
    long moto_target=target;
    while(target!=1){
        loopA-=1;
        while(1){
            loopA++;
            if(loopA>=sqrt(moto_target)+100){
                data[loopB]=target;
                target=1;
                break;
            }
            if(target%loopA==0){
                data[loopB]=loopA;
                target/=loopA;
                loopB++;
                break;
            }
        }
    }
    return ;
}
int get_digit(int target){
    return (int)(log10(target)+1);
}
long ncr(long n , long r){
    return factorial(n)/(factorial(r)*factorial(n-r));
}