思路是先对二进制序列进行排序,然后计算每个元素被选做中位数的次数,将次数乘元素值进行求和。
次数的计算,则是考虑从该元素的左右各选择m个数,m=(k-1)//2,左边记为left,右边记为right。总共就有left*right种可能,也就是会被选中这么多次。
MOD = 10**9 + 7
MAXN = 2 * 10**5 + 10
# 预处理阶乘和逆元
fac = [1] * MAXN
inv = [1] * MAXN
for i in range(1, MAXN):
fac[i] = fac[i - 1] * i % MOD
inv[MAXN - 1] = pow(fac[MAXN - 1], MOD - 2, MOD)
for i in range(MAXN - 2, -1, -1):
inv[i] = inv[i + 1] * (i + 1) % MOD
def C(n, k):
if k < 0 or k > n:
return 0
return fac[n] * inv[k] % MOD * inv[n - k] % MOD
t = int(input())
for _ in range(t):
n, k = map(int, input().split())
lst = list(map(int, input().split()))
# 对二进制序列进行排序
lst.sort()
# 计算每个子序列中间元素的左右两边各有多少元素
m = (k - 1) // 2
res = 0
# 保证左右都能取 m 个
for i in range(m, n - m):
# 左边从i个中挑m个
left = C(i, m)
# 右边从n-i-1中挑n个
right = C(n - i - 1, m)
# 计算这个数被挑做中位数的次数
total = left * right % MOD
# 计算结果
res = (res + lst[i] * total) % MOD
print(res)

京公网安备 11010502036488号