您将获得一个大小为N的列表,用零初始化。您必须在列表上执行M操作并输出列表中所有N个元素的最大值。对于每个操作,您将获得三个整数a,b和k,并且您必须为从索引到(包括两者)的所有元素添加值。
输入格式
第一行将包含由单个空格分隔的两个整数N和M. 接下来的M行将包含由单个空格分隔的三个整数a,b和k。 列表中的数字从1到N编号。
约束
Click here
输出格式
在更新列表中包含最大值的单行。
示例输入
5 3
1 2 100
2 5 100
3 4 100
示例输出
200
解释
第一次更新后的列表将是100 100 0 0 0
第二次更新后的清单将是100 200 100 100 100.
第三次更新后的清单将是100 200 200 200 100.
所以答案必须是200.
时间复杂度较低的解决方案之一
n, inputs = [int(n) for n in input().split(" ")]
list = [0]*(n+1)
for _ in range(inputs):
x, y, incr = [int(n) for n in input().split(" ")]
list[x-1] += incr
if((y)<=len(list)):
list[y] -= incr
max = x = 0
for i in list:
x=x+i;
if(max<x):max=x
print(max)
有人可以解释上述解决方案吗?
答案 0 :(得分:1)
基本上它存储增量而不是最终列表;这意味着每个操作只需要2次读写而不是(b - a + 1)。然后,最后的max
扫描会随着时间的推移添加增量,这仍然是O(n)
操作,无论如何你都必须这样做。
n, inputs = [int(n) for n in input().split(" ")]
获取列表大小(n)和操作数(m),即5
和3
list = [0]*(n+1)
创建一个空的0填充列表。应该是lst = [0] * n
(不要使用list
作为变量名,它会影响内置类型)(我们不需要额外的结束单元格,除非作为我们算法的校验和 - 如果它有效正确的最终校验和应为0)。
for _ in range(inputs):
x, y, incr = [int(n) for n in input().split(" ")]
获取操作(a,b,k),即1
,2
,100
。
list[x-1] += incr
将delta添加到起始单元格
if((y)<=len(list)):
list[y] -= incr
从结束单元格中减去增量(应为if y < n: lst[y] -= incr
)
如果您在此处添加print(lst)
(if
之后但在for
循环内),则该算法可能更容易理解。
现在处理增量以找到最大项目:
max = x = 0
for i in list:
x=x+i;
x
现在是当前列表单元格的实际值。此外,max
是一个可怕的变量名称,因为它会影响内置的max()
函数。
if(max<x):max=x
保持最大运行
print(max)
显示结果。