1. 问题描述:
小蓝发现了一个有趣的数列,这个数列的前几项如下:
1, 1, 2, 1, 2, 3, 1, 2, 3, 4, ...
小蓝发现,这个数列前 1 项是整数 1,接下来 2 项是整数 1 至 2,接下来3 项是整数 1 至 3,接下来 4 项是整数 1 至 4,依次类推。
小蓝想知道,这个数列中,连续一段的和是多少?
输入格式
输入的第一行包含一个整数 T,表示询问的个数。
接下来 T 行,每行包含一组询问,其中第 i 行包含两个整数 li 和 ri,表示询问数列中第 li 个数到第 ri 个数的和。
输出格式
输出 T 行,每行包含一个整数表示对应询问的答案。
样例输入
3
1 1
1 3
5 8
样例输出
1
4
8
评测用例规模与约定
对于 10% 的评测用例, 1 ≤ T ≤ 30, 1 ≤ li ≤ ri ≤ 100。
对于 20% 的评测用例, 1 ≤ T ≤ 100, 1 ≤ li ≤ ri ≤ 1000。
对于 40% 的评测用例, 1 ≤ T ≤ 1000, 1 ≤ li ≤ ri ≤ 10 ^ 6。
对于 70% 的评测用例, 1 ≤ T ≤ 10000, 1 ≤ li ≤ ri ≤ 10 ^ 9。
对于 80% 的评测用例, 1 ≤ T ≤ 1000, 1 ≤ li ≤ ri ≤ 10 ^ 12。
对于 90% 的评测用例, 1 ≤ T ≤ 10000, 1 ≤ li ≤ ri ≤ 10 ^ 12。
对于所有评测用例, 1 ≤ T ≤ 100000, 1 ≤ li ≤ ri ≤ 10 ^ 12。
2. 思路分析:
比较容易想到的是对于当前的端点x,计算出端点x对应的是第几块的数字,在计算是第几块数字的时候计算到当前块的累加和,我们可以使用一个函数来计算[1, x]的和,则区间[li ,ri]的和为[1, ri] - [1, li - 1],模拟整个过程即可。
3. 代码如下:
def cal(x: int):
if x == 0: return 0
base = 0
count_x = 0
sum_x = 0
while base + count_x <= x:
count_x += base
sum_x += count_x
base += 1
sum_x += (1 + x - count_x) * (x - count_x) // 2
return sum_x
if __name__ == '__main__':
n = int(input())
for i in range(n):
l, r = map(int, input().split())
sum_r = cal(r)
sum_l = cal(l - 1)
print(sum_r - sum_l)