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 (Python):
import functools
from heapq import*
from collections import deque
import collections
import math
from collections import defaultdict,Counter
import sys

sys.setrecursionlimit(10 ** 7)
MOD = 10 ** 9 + 7
inf = float("inf")


def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    
    return divisors


def factorize(n):
    fct = []  
    b, e = 2, 0  
    while b * b <= n:
        while n % b == 0:
            n = n // b
            e = e + 1
        if e > 0:
            fct.append((b, e))
        b, e = b + 1, 0
    if n > 1:
        fct.append((n, 1))
    return fct


def is_prime(n):
    if n == 1:
        return False

    for k in range(2, int(math.sqrt(n)) + 1):
        if n % k == 0:
            return False

    return True


def primes(n):
    is_prime = [True] * (n + 1)
    is_prime[0] = False
    is_prime[1] = False
    for i in range(2, int(n**0.5) + 1):
        if not is_prime[i]:
            continue
        for j in range(i * 2, n + 1, i):
            is_prime[j] = False
    return [i for i in range(n + 1) if is_prime[i]]


def modpow(a, n, mod):
    res = 1
    while n > 0:
        if n & 1:
            res = res * a % mod
        a = a * a % mod
        n >>= 1
    return res


def modinv(a, mod):
    return modpow(a, mod - 2, mod)


def cnk(a, b):
    MOD = 10**9+7
    ret = 1
    for i in range(b):
        ret *= (a-i)
        ret %= MOD
        ret = ret * modinv(i+1, MOD) % MOD
    return ret


def Dijkstra(n, start, e):
    
    
    
    
    n += 10

    d = [float("inf") for i in range(n)]
    d[start] = 0

    pathnum = [0 for i in range(n)]
    pathnum[start] = 1

    visited = [False for i in range(n)]
    q = []
    heappush(q, (0, start))
    while len(q):
        now_distance, v = heappop(q)
        if visited[v]:
            continue
        visited[v] = True
        for next_v, next_distance in e[v]:
            if visited[next_v]:
                continue
            dd = now_distance + next_distance
            if d[next_v] > dd:
                d[next_v] = dd
                heappush(q, (dd, next_v))
            if d[next_v] == dd:
                pathnum[next_v] += pathnum[v]
                pathnum[next_v] %= MOD

    return d, pathnum


def warshall_floyd(d):
    for k in range(n):
        for i in range(n):
            for j in range(n):
                d[i][j] = min(d[i][j], d[i][k] + d[k][j])
    return d


class UnionFind:
    def __init__(self, n):
        self.sz = [-1 for i in range(n)]

    
    def find(self, x):
        if self.sz[x] < 0:
            return x
        else:
            self.sz[x] = self.find(self.sz[x])
            return self.sz[x]

    

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return False
        if self.sz[x] > self.sz[y]:
            x, y = y, x
        self.sz[x] += self.sz[y]
        self.sz[y] = x

    
    def same(self, x, y):
        return self.find(x) == self.find(y)

    
    def size(self, x):
        return -self.sz[self.find(x)]


class WeightedUnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        
        self.weight = [0] * (n+1)

    
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            y = self.find(self.par[x])
            
            self.weight[x] += self.weight[self.par[x]]
            self.par[x] = y
            return y

    
    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)
        
        if self.rank[rx] < self.rank[ry]:
            self.par[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        
        else:
            self.par[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    
    def same(self, x, y):
        return self.find(x) == self.find(y)

    
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]






@functools.lru_cache(maxsize=None)
class UNION_FIND(object):
    def __init__(self, n):
        self.parent = [-1 for i in range(n)]

    def root(self, x):
        if self.parent[x] < 0:
            return x
        else:
            self.parent[x] = self.root(self.parent[x])
            return self.parent[x]

    def size(self, x):
        return -self.parent[self.root(x)]

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        if self.size(x) < self.size(y):
            x, y = y, x
        self.parent[x] += self.parent[y]
        self.parent[y] = x
        return True


def compute_mst_kruskal(max_v, edges):
    edges.sort(key=lambda x: x[2], reverse=1)
    uf = UNION_FIND(max_v)
    mst = []
    for (a, b, c, d) in edges:
        if uf.root(a-1) != uf.root(b-1):
            uf.union(a-1, b-1)
            mst += [d+1]
    return mst

















class Dinic:
    def __init__(self, N):
        self.N = N
        self.G = [[] for i in range(N)]

    def add_edge(self, fr, to, cap):
        forward = [to, cap, None]
        forward[2] = backward = [fr, 0, forward]
        self.G[fr].append(forward)
        self.G[to].append(backward)

    def add_multi_edge(self, v1, v2, cap1, cap2):
        edge1 = [v2, cap1, None]
        edge1[2] = edge2 = [v1, cap2, edge1]
        self.G[v1].append(edge1)
        self.G[v2].append(edge2)

    def bfs(self, s, t):
        self.level = level = [None]*self.N
        deq = deque([s])
        level[s] = 0
        G = self.G
        while deq:
            v = deq.popleft()
            lv = level[v] + 1
            for w, cap, _ in G[v]:
                if cap and level[w] is None:
                    level[w] = lv
                    deq.append(w)
        return level[t] is not None

    def dfs(self, v, t, f):
        if v == t:
            return f
        level = self.level
        for e in self.it[v]:
            w, cap, rev = e
            if cap and level[v] < level[w]:
                d = self.dfs(w, t, min(f, cap))
                if d:
                    e[1] -= d
                    rev[1] += d
                    return d
        return 0

    def flow(self, s, t):
        flow = 0
        INF = 10**9 + 7
        G = self.G
        while self.bfs(s, t):
            *self.it, = map(iter, self.G)
            f = INF
            while f:
                f = self.dfs(s, t, INF)
                flow += f
        return flow



















ok = [False for i in range(2505)]


def Bellmanford(edges, n, s):
    d = [float("inf") for i in range(n)]
    d[s] = 0

    for i in range(n):
        for x, y, z in edges:
            if not ok[x] or not ok[y]:  
                continue
            if d[y] > d[x] + z:
                d[y] = d[x] + z
                if i == n - 1:
                    print(-1)
                    exit()
    print(max(0, -d[n - 1]))


def nck(n, k):
    ret = 1
    for i in range(min(n - k, k)):
        ret *= (n - i)
        ret /= (i + 1)
    return ret


def main():
    n, a, b = map(int, input().split())
    v = list(map(int, input().split()))

    v = sorted(v, reverse=True)
    
    
    
    d = Counter(v)
    value = 0
    t = 0
    for i in range(a):
        value += v[i]
        if i == a - 1:
            t = v[i]
    print(value / a)

    c = 0
    for i in range(n):
        if v[i] == t:
            break
        c += d[v[i]]

    ans = 0
    if d[v[0]] > a:
        for i in range(a, min(b,d[v[0]])+1):
            ans += nck(d[v[0]], i)
        print(int(ans))
    else:
        print(int(nck(d[t], a - c)))


if __name__ == '__main__':
    main()

Solution (Python):
import functools
from heapq import*
from collections import deque
import collections
import math
from collections import defaultdict
import sys

sys.setrecursionlimit(10 ** 7)
MOD = 10 ** 9 + 7
inf = float("inf")


def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)

    
    return divisors


def factorize(n):
    fct = []  
    b, e = 2, 0  
    while b * b <= n:
        while n % b == 0:
            n = n // b
            e = e + 1
        if e > 0:
            fct.append((b, e))
        b, e = b + 1, 0
    if n > 1:
        fct.append((n, 1))
    return fct


def is_prime(n):
    if n == 1:
        return False

    for k in range(2, int(math.sqrt(n)) + 1):
        if n % k == 0:
            return False

    return True


def primes(n):
    is_prime = [True] * (n + 1)
    is_prime[0] = False
    is_prime[1] = False
    for i in range(2, int(n**0.5) + 1):
        if not is_prime[i]:
            continue
        for j in range(i * 2, n + 1, i):
            is_prime[j] = False
    return [i for i in range(n + 1) if is_prime[i]]


def modpow(a, n, mod):
    res = 1
    while n > 0:
        if n & 1:
            res = res * a % mod
        a = a * a % mod
        n >>= 1
    return res


def modinv(a, mod):
    return modpow(a, mod - 2, mod)


def cnk(a, b):
    MOD = 10**9+7
    ret = 1
    for i in range(b):
        ret *= (a-i)
        ret %= MOD
        ret = ret * modinv(i+1, MOD) % MOD
    return ret


def Dijkstra(n, start, e):
    
    
    
    
    n += 10

    d = [float("inf") for i in range(n)]
    d[start] = 0

    pathnum = [0 for i in range(n)]
    pathnum[start] = 1

    visited = [False for i in range(n)]
    q = []
    heappush(q, (0, start))
    while len(q):
        now_distance, v = heappop(q)
        if visited[v]:
            continue
        visited[v] = True
        for next_v, next_distance in e[v]:
            if visited[next_v]:
                continue
            dd = now_distance + next_distance
            if d[next_v] > dd:
                d[next_v] = dd
                heappush(q, (dd, next_v))
            if d[next_v] == dd:
                pathnum[next_v] += pathnum[v]
                pathnum[next_v] %= MOD

    return d, pathnum


def warshall_floyd(d):
    for k in range(n):
        for i in range(n):
            for j in range(n):
                d[i][j] = min(d[i][j], d[i][k] + d[k][j])
    return d


class UnionFind:
    def __init__(self, n):
        self.sz = [-1 for i in range(n)]

    
    def find(self, x):
        if self.sz[x] < 0:
            return x
        else:
            self.sz[x] = self.find(self.sz[x])
            return self.sz[x]

    

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return False
        if self.sz[x] > self.sz[y]:
            x, y = y, x
        self.sz[x] += self.sz[y]
        self.sz[y] = x

    
    def same(self, x, y):
        return self.find(x) == self.find(y)

    
    def size(self, x):
        return -self.sz[self.find(x)]


class WeightedUnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        
        self.weight = [0] * (n+1)

    
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            y = self.find(self.par[x])
            
            self.weight[x] += self.weight[self.par[x]]
            self.par[x] = y
            return y

    
    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)
        
        if self.rank[rx] < self.rank[ry]:
            self.par[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        
        else:
            self.par[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    
    def same(self, x, y):
        return self.find(x) == self.find(y)

    
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]






@functools.lru_cache(maxsize=None)
class UNION_FIND(object):
    def __init__(self, n):
        self.parent = [-1 for i in range(n)]

    def root(self, x):
        if self.parent[x] < 0:
            return x
        else:
            self.parent[x] = self.root(self.parent[x])
            return self.parent[x]

    def size(self, x):
        return -self.parent[self.root(x)]

    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        if self.size(x) < self.size(y):
            x, y = y, x
        self.parent[x] += self.parent[y]
        self.parent[y] = x
        return True


def compute_mst_kruskal(max_v, edges):
    edges.sort(key=lambda x: x[2], reverse=1)
    uf = UNION_FIND(max_v)
    mst = []
    for (a, b, c, d) in edges:
        if uf.root(a-1) != uf.root(b-1):
            uf.union(a-1, b-1)
            mst += [d+1]
    return mst

















class Dinic:
    def __init__(self, N):
        self.N = N
        self.G = [[] for i in range(N)]

    def add_edge(self, fr, to, cap):
        forward = [to, cap, None]
        forward[2] = backward = [fr, 0, forward]
        self.G[fr].append(forward)
        self.G[to].append(backward)

    def add_multi_edge(self, v1, v2, cap1, cap2):
        edge1 = [v2, cap1, None]
        edge1[2] = edge2 = [v1, cap2, edge1]
        self.G[v1].append(edge1)
        self.G[v2].append(edge2)

    def bfs(self, s, t):
        self.level = level = [None]*self.N
        deq = deque([s])
        level[s] = 0
        G = self.G
        while deq:
            v = deq.popleft()
            lv = level[v] + 1
            for w, cap, _ in G[v]:
                if cap and level[w] is None:
                    level[w] = lv
                    deq.append(w)
        return level[t] is not None

    def dfs(self, v, t, f):
        if v == t:
            return f
        level = self.level
        for e in self.it[v]:
            w, cap, rev = e
            if cap and level[v] < level[w]:
                d = self.dfs(w, t, min(f, cap))
                if d:
                    e[1] -= d
                    rev[1] += d
                    return d
        return 0

    def flow(self, s, t):
        flow = 0
        INF = 10**9 + 7
        G = self.G
        while self.bfs(s, t):
            *self.it, = map(iter, self.G)
            f = INF
            while f:
                f = self.dfs(s, t, INF)
                flow += f
        return flow



















ok = [False for i in range(2505)]


def Bellmanford(edges, n, s):
    d = [float("inf") for i in range(n)]
    d[s] = 0

    for i in range(n):
        for x, y, z in edges:
            if not ok[x] or not ok[y]:  
                continue
            if d[y] > d[x] + z:
                d[y] = d[x] + z
                if i == n - 1:
                    print(-1)
                    exit()
    print(max(0, -d[n - 1]))


def nck(n, k):
    ret = 1
    for i in range(min(n - k, k)):
        ret *= (n - i)
        ret /= (i + 1)
    return ret


def main():
    n, a, b = map(int, input().split())
    v = list(map(int, input().split()))

    v = sorted(v, reverse=True)
    d = defaultdict(int)
    for i in range(n):
        d[v[i]] += 1
    value = 0
    t = 0
    for i in range(a):
        value += v[i]
        if i == a - 1:
            t = v[i]
    print(value / a)

    c = 0
    for i in range(n):
        if v[i] == t:
            break
        c += d[v[i]]

    ans = 0
    if d[v[0]] > a:
        for i in range(a, min(b,d[v[0]])+1):
            ans += nck(d[v[0]], i)
        print(int(ans))
    else:
        print(int(nck(d[t], a - c)))


if __name__ == '__main__':
    main()

Solution (Python):
def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result

N,A,B = list(map(int,input().split()))
v = list(map(int,input().split()))
v.sort(reverse=True)

data = []
cnt = 0
ans = 0
for i in v:
  data.append(i)
  cnt += 1
  if cnt == A:
    vnum = v.count(i)
    datanum = data.count(i)
    if cnt == datanum:
      for j in range(A,min(B, vnum)+1):
        
        ans += cmb(vnum, j)
      break
    else:
      ans = cmb(vnum, datanum)
      
      break
print(sum(data)/len(data))
print(ans)

Solution (Python):
def comb(N):
    for i in range(N+1):
        for j in range(i+1):
            if j == 0 or j == i :
                dp[i][j] = 1
            else:
                dp[i][j] = dp[i-1][j-1] + dp[i-1][j]

def main():
    global dp,N
    N, A, B = map(int, input().split())
    v = [int(i) for i in input().split()]
    v.sort(reverse=True)
    dp = [[0 for i in range(N+1)] for j in range(N+1)]
    ans = 0
    for i in range(A):
        ans += v[i]
    ans /= A
    a = 0
    b = 0
    for i in range(N):
        if v[A-1] == v[i]:
            a += 1
            if i < A :
                b += 1
    ans_2 = 0
    comb(N)
    if v[A-1] == v[0]:
        for i in range(A,B+1):
            ans_2 += dp[a][i]
    else:
        ans_2 += dp[a][b]
    print(ans,ans_2)


if __name__ == '__main__':
    main()

Solution (Python):
from operator import mul
from functools import reduce

def cmb(n,r):
    r = min(n-r,r)
    if r == 0: return 1
    over = reduce(mul, range(n, n - r, -1))
    under = reduce(mul, range(1,r + 1))
    return over // under

def main():
    N, A, B = map(int, input().split())
    v = list(map(int, input().split()))
    sort_v = sorted(v, reverse=True)
    sum_A = 0
    for i in range(A):
        sum_A += sort_v[i]
    max_ave_v = sum_A / A

    print(max_ave_v)

    num = sort_v.count(sort_v[0])
    num2 = sort_v.count(sort_v[A-1])
    if sort_v[0] == sort_v[A-1]:
        ans = 0
        for i in range(A,B+1):
            if num >= i:
                ans += cmb(num,i)
    else:
        cnt = 0
        for i in range(A):
            if sort_v[i] == v[A-1]:
                cnt += 1
        ans = cmb(num2, cnt)

    print(ans)
        


main()

Solution (Python):
import math
n,a,b=map(int,input().split())
v=list(map(int,input().split()))
v.sort()
v.reverse()
if a==n:
  print(sum(v)/n)
  print(1)
elif v[a-1]!=v[a]:
  print(sum(v[0:a])/a)
  print(1)
elif v[0]!=v[a-1]:
  print(sum(v[0:a])/a)
  ct1=0;ct2=0
  for i in range(n):
    if v[i]==v[a-1]:
      ct1+=1
      if i<a:
        ct2+=1
  print(math.factorial(ct1)//(math.factorial(ct1-ct2)*math.factorial(ct2)))
else:
  print(sum(v[0:a])/a)
  ct1=0;ans=0
  for i in range(n):
    if v[i]==v[a-1]:
      ct1+=1
  for i in range(a,min(ct1+1,b+1)):
    ans+=math.factorial(ct1)//(math.factorial(ct1-i)*math.factorial(i))
  print(ans)

Solution (Python):
def main():

    N, A, B = map(int, input().split())
    v = list(map(int, input().split()))
    v.sort(reverse = True)

    if all(v[i] == v[0] for i in range(A)):
        ct = 0
        for i in range(N):
            if v[i] == v[0]:
                ct += 1
        cases = [1]
        for i in range(1, ct+1):
            cases.append(cases[-1]*(ct-i+1)//i)
        return v[0], sum(cases[A:(min(ct, B)+1)])
    else:
        i = 0
        tot = 0
        while i < A:
            tot += v[i]
            i += 1
        max_i = i
        ref = v[i-1]
        ct_used = 0
        for j in range(A):
            if v[j] == ref:
                ct_used += 1

        ct = 0
        for j in range(N):
            if v[j] == ref:
                ct += 1
        cases = 1
        for j in range(1, ct_used+1):
            cases = cases * (ct-j+1)//j
        return tot/max_i, cases

if __name__ == '__main__':
    output = main()
    for v in output:
        print(v)

Solution (Python):

import sys

f = [1]
for i in range(1, 51):
    f.append(f[-1] * i)

def comb(n, k):
    a = f[n]
    b = f[n-k]
    c = f[k]
    bc = b * c
    return a // bc

def solve(N: int, A: int, B: int, v: "List[int]"):
    v = sorted(v, reverse=True)
    print("%.6f" % (sum(v[:A])/A))

    if v[0] != v[A]:
        ret = comb(v.count(v[A-1]), v[:A].count(v[A-1]))
        print(ret)
    else:
        s = 0
        X = v.count(v[0])
        for i in range(A, B+1):
            s += comb(X, i)
        print(s)
    return



def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    A = int(next(tokens))  
    B = int(next(tokens))  
    v = [int(next(tokens)) for _ in range(N)]  
    solve(N, A, B, v)

if __name__ == '__main__':
    main()

Solution (Python):
import collections
import math
N,A,B  = map(int, input().split())
v = list(map(int,input().split()))

nums = collections.defaultdict(int)
for x in v:
    nums[x] += 1
ave = [[0 for i in range (B - A + 1)] for j in range(2)]
v.sort(reverse = True)
for i in range(A , B + 1):
    ave[0][i - A] = sum(v[:i]) / i
    ave[1][i - A] = v[:i]
ans = max(ave[0])
print(ans)

indexes = [i for i in range(B - A + 1) if ave[0][i] == ans]
max_counter = [] * len(indexes)
ans = 0
for i in indexes:
    counter = collections.Counter(ave[1][i])
    tmp_ans = 1
    for x in counter:
        tmp_ans *= math.factorial(nums[x]) // math.factorial(counter[x]) // math.factorial(nums[x] - counter[x])
    ans += tmp_ans
print(ans)

Solution (Python):
from math import factorial


def comb(a, b):
    if b < 0 or a < b:
        return 0
    return factorial(a) // factorial(b) // factorial(a - b)


N, A, B = map(int, input().split())
V = [int(s) for s in input().split()]
V.sort(reverse=True)
ans1 = sum(V[:A]) / A
num = V.count(V[A - 1])
if V[0] == V[A - 1]:
    ans2 = sum([comb(num, m) for m in range(A, B + 1)])
else:
    m = V[:A].count(V[A - 1])
    ans2 = comb(num, m)
print(ans1)
print(ans2)

Solution (Python):
n,a,b=map(int,input().split())
v=[int(i) for i in input().split()]
v.sort()
v.reverse()
ans=0
from collections import Counter
c=Counter()
k=0
tmp=0
for i in range(n):
    if i<a-1:
        ans+=v[i]
        c[v[i]]+=1
    elif i==a-1:
        tmp=v[i]
        c[v[i]]+=1
        ans+=v[i]
    else:
        if tmp!=v[i]:
            break
        else:
            c[v[i]]+=1
            k+=1
ans=ans/a
print(ans)
def f(n,m):
    import math
    if n-m<0:
        return 0
    return(math.factorial(n)//math.factorial(n-m)//math.factorial(m))
ans2=0

if ans==tmp:
    for i in range(c[tmp]-k,c[tmp]-k+b-a+1):
        ans2+=f(c[tmp],i)
    print(ans2)
else:
    print(f(c[tmp],k))

Solution (Python):
N, A, B = map(int, input().split())
val = [int(i) for i in input().split()]

def combi(n, m):
    from math import factorial
    return factorial(n) // (factorial(m) * factorial(n-m))

val.sort(reverse=True)
ave = sum(val[:A])/A

l = val.index(val[A-1])
x = val.count(val[A-1])
ct = 0

if val[0] == val[A-1]:
    for i in range(A, x+1):
        if i > B:
            break
        else:
            ct += combi(x, i)
else:
    ct = combi(x, A-l)
print(ave)
print(ct)

Solution (Python):
import sys
input=sys.stdin.readline
n,a,b=map(int,input().split())
v_list=list(map(int,input().split()))
v_list.sort(reverse=True)
x=v_list[a-1]
print(sum(v_list[:a])/a)
import math
if v_list[0]==x:
    count=0
    for i in range(n):
        if v_list[i]==x:
            count+=1
    ans=0
    for i in range(a,min(b,count)+1):
        ans+=math.factorial(count)//(math.factorial(i)*math.factorial(count-i))
    print(ans)
else:
    counta=0
    for i in range(a):
        if v_list[i]==x:
            counta+=1
    count=0
    for i in range(n):
        if v_list[i]==x:
            count+=1
    ans=math.factorial(count)//(math.factorial(counta)*math.factorial(count-counta))
    print(ans)

Solution (Python):
import sys
input=sys.stdin.readline
n,a,b=map(int,input().split())
v_list=list(map(int,input().split()))
v_list.sort(reverse=True)
x=v_list[a-1]
print(sum(v_list[:a])/a)
import math
if v_list[0]==x:
    count=0
    for i in range(n):
        if v_list[i]==x:
            count+=1
    ans=0
    for i in range(a,min(b,count)+1):
        ans+=math.factorial(count)//(math.factorial(i)*math.factorial(count-i))
    print(ans)
else:
    counta=0
    for i in range(a):
        if v_list[i]==x:
            counta+=1
    count=0
    for i in range(n):
        if v_list[i]==x:
            count+=1
    ans=math.factorial(count)//(math.factorial(counta)*math.factorial(count-counta))
    print(ans)

Solution (Python):
nCk = [[0 for i in range(51)] for j in range(51)]

nCk[1][0] = 1
nCk[1][1] = 1
for i in range(2, 51):
    for j in range(51):
        if j > 0:
            nCk[i][j] = nCk[i-1][j-1] + nCk[i-1][j]
        else:
            nCk[i][j] = nCk[i-1][j]

N, A, B = map(int,input().split())
kouho = []
V = list(map(int,input().split()))
V.sort(reverse = True)
acc = 0
for i in range(B):
    if i < A-1:
        acc += V[i]
    else:
        acc += V[i]
        kouho.append(acc / (i+1))

print(str(kouho[0]))

cnt = 0
for i in range(len(kouho)):
    m = 0
    n = 0
    if kouho[i] != kouho[0]:
        break
    for j in range(N):
        if V[j] == V[A+i-1]:
            if j < A+i:
                m+=1
            n+=1
    cnt += nCk[n][m]
print(str(cnt))

Solution (Python):
from bisect import bisect_left
from operator import mul
from functools import reduce

N, A, B = map(int, input().split())
V = list(map(int, input().split()))

V.sort(reverse=True)




def cmb(n,r):
    r = min(n-r,r)
    if r == 0: return 1
    over = reduce(mul, range(n, n - r, -1))
    under = reduce(mul, range(1,r + 1))
    return over // under

print(sum(V[:A])/len(V[:A]))

c = 0
for i in range(A-1, B):
    if V[i] == V[A-1]:
        c += 1


for i, v in enumerate(V):
    if v == V[A-1]:
        ia = i
        break
l = A - ia
maxl = V.count(V[A-1])

if ia == 0:
    ans = 0
    for d in range(c):
        ans += cmb(maxl, l+d)
else:
    ans = cmb(maxl, l)
print(ans)

Solution (Python):
import collections
from math import factorial
def comb(n,r):
    return factorial(n)//factorial(n-r)//factorial(r)
n,a,b=map(int,input().split())
v=list(map(int,input().split()))
v.sort(reverse=True)
c=collections.Counter(v)
k=min(v[:a])
if c[max(v)]<a:
    ans=comb(c[k],v[:a].count(k))
else:
    ans=0
    for i in range(a,min(b,c[k])+1):
        ans+=comb(c[k],i)
print(sum(v[:a])/a)
print(ans)

Solution (Python):

import sys
from statistics import mean
from bisect import bisect_left
INF = float("inf")


def cmb(n, r):
    if r < 0 or n < r:
        return 0
    r = min(r, n-r)
    if r == 0:
        return 1
    if r == 1:
        return n

    numer = [n - r + k + 1 for k in range(r)]
    denom = [k + 1 for k in range(r)]

    for p in range(2, r+1):
        pivot = denom[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1, r, p):
                numer[k - offset] /= pivot
                denom[k] /= pivot

    result = 1
    for k in range(r):
        if numer[k] > 1:
            result *= int(numer[k])

    return result


def solve(N: int, A: int, B: int, v: "List[int]"):
    v.sort()
    ave = mean(v[N-A:])
    ma = v[-1]
    print(ave)

    num = v.count(v[N-A])
    hamidashi = v[:N-A].count(v[N-A])
    if ma == ave and hamidashi > 0:
        
        
        tot = 0
        for i in range(A, B+1):
            
            tot += cmb(num, i)
        print(tot)
    else:
        print(cmb(num, hamidashi))
    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    A = int(next(tokens))  
    B = int(next(tokens))  
    v = [int(next(tokens)) for _ in range(N)]  
    solve(N, A, B, v)


if __name__ == '__main__':
    main()

Solution (Python):

from collections import Counter

N, A, B = map(int, input().split())

v = list(map(int, input().split()))
v.sort(reverse=True)

ave_max = sum(v[:A]) / A

counter = Counter(v)
cnt = counter[v[0]]

ans = 0
nCr = {}
def cmb(n, r):
    if r == 0 or r == n: return 1
    if r == 1: return n
    if (n,r) in nCr: return nCr[(n,r)]
    nCr[(n,r)] = cmb(n-1,r) + cmb(n-1,r-1)
    return nCr[(n,r)]
if cnt < A:
    m = v[A-1]
    n = counter[m] 
    r = v[:A].count(m)
    ans = cmb(n,r)
elif cnt == A:
    ans = 1
    
else:
    for i in range(A, min(cnt, B) + 1):

        ans += cmb(cnt, i)

print(ave_max)
print(ans)

Solution (Python):



import sys
sys.setrecursionlimit(10**6)
readline = sys.stdin.readline 


def choose(n,k):
    if 0 <= k <= n:
        res = 1
        for i in range(k):
            res *= n-i
            res //= (i+1)
        return res
    else:
        return 0


n,a,b = [int(i) for i in readline().split()]
v = [int(i) for i in readline().split()]

v.sort(reverse=True)
s = sum(v[:a])

print(s/a)
from bisect import *

c = v[a]
ans = 0
if v[a-1] != v[a]:
    ans = 1
else:    
    v.sort()
    l = bisect_left(v,c)
    r = bisect_right(v,c)
    if r != n:
        ans = choose(r-l,r+a-n)
    else:
        for i in range(r+a-n,r+b-n+1):
            ans += choose(r-l,i)

print(ans)