题目描述
给定一个数组 A 和一些查询 Li , Ri,求数组中第 Li 至第 Ri 个元素之和。
小蓝觉得这个问题很无聊,于是他想重新排列一下数组,使得最终每个查询结果的和尽可能地大。小蓝想知道相比原数组,所有查询结果的总和最多可以增加多少?
输入格式
输入第一行包含一个整数 n。
第二行包含 n 个整数 A1, A2, · · · , An,相邻两个整数之间用一个空格分隔。
第三行包含一个整数 m 表示查询的数目。
接下来 m 行,每行包含两个整数 Li、Ri ,相邻两个整数之间用一个空格分隔。
输出格式
输出一行包含一个整数表示答案。
样例输入
5 1 2 3 4 5 2 1 3 2 5
样例输出
4
提示
原来的和为 6 + 14 = 20,重新排列为 (1, 4, 5, 2, 3) 后和为 10 + 14 = 24,增加了 4。
对于 30% 的评测用例,n, m ≤ 50 ;
对于 50% 的评测用例,n, m ≤ 500 ;
对于 70% 的评测用例,n, m ≤ 5000 ;
对于所有评测用例,1 ≤ n, m ≤ 105,1 ≤ Ai ≤ 106,1 ≤ Li ≤ Ri ≤ 106 。
思路解答:
记录被访问次数, 被访问次数多的下标应该对应较大的数,这样才可以使结果尽量大。
源码:
n = int(input())
ls = list(map(int, input().split()))
m = int(input())
lrls = [list(map(int, input().split())) for _ in range(m)]
# 记录被访问次数, 被访问次数多的下标应该对应较大的数,这样才可以使结果尽量大
weightls = [0 for _ in range(n)]
for lr in lrls:
weightls[lr[0]-1:lr[1]] = map(lambda x: x+1, weightls[lr[0]-1:lr[1]])
# 依据访问次数,对下标进行排序(降序)
sortedWeightls = [(index, weight) for index, weight in enumerate(weightls)]
sortedWeightls = sorted(sortedWeightls, key=lambda x: x[1], reverse=True) #默认升序
sortIndexls = [t[0] for t in sortedWeightls]
# 同时也对原数组进行排序,排完序后,依照排好序的下标依次放入结果数组
tls = sorted(ls, reverse=True)
sortedls = [0 for _ in tls]
for index1, index2 in enumerate(sortIndexls):
sortedls[index2] = tls[index1]
res = 0
for lr in lrls:
res += sum(sortedls[lr[0]-1: lr[1]]) - sum(ls[lr[0]-1: lr[1]])
print(res)