来来来,咱先明确一个概念,“不超过”就是<= ,翻译一下题目 ,假设我们的研究对象,就是研究的这个同学,他叫小明,本题的意思就是,要求小明刷题,最后:
比小明刷题多的人<=比小明刷题少的人
也就是比小明刷题少的人>=比小明刷题多的人,这样更方便,因为我们写数据的时候习惯从前写。
之后咱就用前缀和这个算法,记录每个分段的人数,及更新数组,使他记录这个分段及这个分段之前有多少人刷题,之后应该会有一个常数,就是这个分段的同学刷题数量刚好使两边同学相等,
找到这个分段,再处理一些细节,题目就完成了。
N = 100000
cnt = [0] * (N + 1) # cnt[i] = number of elements <= i
#用到了前缀和
less = lambda i: cnt[i - 1] if i else 0
#意思是i如果为零,返回0,剩下返回cnt[i-1]
#cnt[i-1]的意思是刷题比这个同学少的同学数量
more = lambda i: cnt[N] - cnt[i]
#刷题比这个同学多的同学数量
if __name__ == '__main__':
n = int(input())
a = [int(x) for x in input().split()]
for x in a:
cnt[x] += 1#记录了每个刷题分段有多少同学
for i in range(1, N + 1):#更新数组,使得数组记录每个刷题分段有多少同学刷题不超过这个分段的刷题数
cnt[i] += cnt[i - 1]
for i in range(N + 1):#这个东西是个常数,本题的点睛之处,就是最小刷题数
#我们对分数遍历
if less(i)-1 >= more(i):#这句话的意思也是刷题比这个同学少的同学数量大于等于刷题比这个同学多的同学数量
#这地方最难理解
#为什么要减一
#因为如果不减一那么仅仅是刷到这个地方,如果less(i)<=more(i)的话还是不够的
#所以我们要更上一层楼,进行必杀
min_law = i
break
for x in a:
print(0 if less(x) >= more(x) else min_law-x, end = " ")
其实找那个min_law可以用二分优化,但是我不想写了。