假定有一个无限长的数轴,数轴上每个坐标上的数都是 0。 现在,我们首先进行 n次操作,每次操作将某一位置 x上的数加 c。 接下来,进行 m次询问,每个询问包含两个整数 l和 r,你需要求出在区间 [l,r]之间的所有数的和。
输入格式
第一行包含两个整数 n和 m。 接下来 n行,每行包含两个整数 x和 c。再接下来 m行,每行包含两个整数 l和 r 。
输出格式
共 m行,每行输出一个询问中所求的区间内数字和。
数据范围
−10^9 ≤ x ≤ 10^9,
1 ≤ n, m ≤ 10^5,
−10^9 ≤ l ≤ r ≤ 10^9,
−10000 ≤ c ≤ 10000
输入样例:
3 3
1 2
3 6
7 5
1 3
4 6
7 8
输出样例:
8
0
5
代码
知识点:离散化
# 查询l,r很大会MLE,但是稀疏,可以离散化处理
N = 300010 # 3 * 10^5 ,x,l,r最大分别为10^5
n,m = map(int,input().split())
query = []
idxarr = [] # 存放真正用到的下标
add = []
for _ in range(n):
x , c = map(int,input().split())
add.append((x,c))
idxarr.append(x)
for _ in range(m):
l,r = map(int,input().split())
query.append((l,r))
idxarr.append(l)
idxarr.append(r)
idxarr = sorted(list(set(idxarr))) # 原数组,包含所有的查询和加c的下标,去重排序,便于二分查找
from bisect import bisect_left
def find(i):
return bisect_left(idxarr,i) + 1 # 下标是1开始
maparr = [0 for _ in range(N)] # 映射数组
for x,c in add:
maparr[find(x)] += c
presum = [0 for _ in range(N)] #前缀和
for i in range(1,len(idxarr) + 2):
presum[i] = presum[i-1] + maparr[i]
for l,r in query:
print(presum[find(r)] - presum[find(l)-1])