算法知识点:二分,差分
复杂度:
解题思路:
由于随着订单数量的增加,每天可用教室的数量一定单调下降。
因此我们可以二分出第一天出现负值的订单编号。
剩下的问题是如何快速求出经过若干订单后,每天所剩的教室数量。
每个订单的操作是 全部减去 。
因此我们可以用差分来加速处理过程。
时间复杂度分析:
总共二分 次,其中 是订单数量。每次二分后使用差分求出每天最终教室数量,计算量是 ,因此总时间复杂度是 。
C++ 代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; const int N = 1000010; int n, m; int r[N], d[N], s[N], t[N]; LL b[N]; bool check(int k) { for (int i = 1; i <= n; i++) b[i] = r[i]; for (int i = 1; i <= k; i++) { b[s[i]] -= d[i]; b[t[i] + 1] += d[i]; } LL res = 0; for (int i = 1; i <= n; i++) { res += b[i]; if (res < 0) return true; } return false; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) scanf("%d", &r[i]); for (int i = n; i; i--) r[i] -= r[i - 1]; for (int i = 1; i <= m; i++) scanf("%d%d%d", &d[i], &s[i], &t[i]); int l = 1, r = m; while (l < r) { int mid = l + r >> 1; if (check(mid)) r = mid; else l = mid + 1; } if (check(r)) { puts("-1"); printf("%d\n", r); } else puts("0"); return 0; }