第一天:二分
题目引入
有n天,第i天有相应的教室数量ai。
有m份订单,订单编号从 1 到 m 逐次递增,订单内容为d,l,r,表示在 第 l 到 r 天,每天都租借d间教室。
计算出哪一份订单最先无法满足,输出其订单编号。
数据范围
0 <= n,m <= 1e6; 0 <= ai,d <= 1e9; 1 <= l,r <= n
输入
n m
a1 a2 a3 ... an
d l r
.........
输出
如果都可以满足,输出0;否则第一行输出-1,第二行输出对应的订单编号(最先无法满足)
示例
输入
4 3
2 5 4 3
2 1 3
3 2 4
4 2 4
输出
-1
2
代码
import sys
sys.setrecursionlimit(1000000)
input = lambda: sys.stdin.readline().strip()
r1 = lambda: int(input())
r2 = lambda: map(int, input().split())
r3 = lambda: [*map(int, input().split())]
def solve():
n,m = r2()
a = r3()
query = [[]for _ in range(m + 1)]
for i in range(1,m + 1):
query[i] = r3()
def check(x):
diff = [0] * (n + 2)
for i in range(1,x + 1):
d,l,r = query[i]
diff[l] += d
diff[r + 1] -= d
s = 0
for i in range(1,n + 1):
s += diff[i]
x = a[i - 1]
if s > x:
return False
return True
l,r = 0,m
while l < r:
mid = l + r + 1 >> 1
if check(mid):
l = mid
else:
r = mid - 1
if l == m:
print(0)
else:
print(-1)
print(l + 1)
if __name__ == "__main__":
t = 1
for _ in range(t):
solve()
模板总结
0001111100000
①寻找最左边的1
while l < r:
mid = l + r >> 1
if check(mid):
r = mid
else:
l = mid + 1
②寻找最右边的1
while l < r:
mid = l + r + 1>> 1
if check(mid):
l = mid
else:
r = mid - 1

浙公网安备 33010602011771号