第一种方法:可以二分最大天数订单的答案然后通过差分求一下是否可行。
1 const int maxn = 1e6 + 5; 2 int n, m, a[maxn], ans; 3 struct section { 4 int cnt, l, r; 5 }b[maxn]; 6 int c[maxn], sum[maxn]; 7 8 inline bool ok(int now) { 9 init(c, 0); 10 rep(i, 1, now) { 11 auto tmp = b[i]; 12 c[tmp.l] -= tmp.cnt; 13 c[tmp.r + 1] += tmp.cnt; 14 } 15 rep(i, 1, n) { 16 sum[i] = sum[i - 1] + c[i]; 17 if (sum[i] + a[i] < 0) return false; 18 } 19 return true; 20 } 21 22 int main() { 23 read(n), read(m); 24 rep(i, 1, n) read(a[i]); 25 rep(i, 1, m) { 26 read(b[i].cnt); 27 read(b[i].l); 28 read(b[i].r); 29 } 30 31 int l = 1, r = m; 32 while (l <= r) { 33 int mid = (l + r) >> 1; 34 if (ok(mid)) { 35 l = mid + 1; 36 } else { 37 ans = mid; 38 r = mid - 1; 39 } 40 } 41 42 if (!ans) writeln(0); 43 else { 44 writeln(-1); 45 writeln(ans); 46 } 47 return 0; 48 }
第二种方法:无脑插一棵残缺的线段树板子即可:
1 const int maxn = 1e6 + 5; 2 int n, m; 3 struct Node { 4 int l, r, minn, tag; 5 }t[maxn << 2]; 6 #define ls(p) p << 1 7 #define rs(p) p << 1 | 1 8 9 void Build(int l, int r, int p) { 10 t[p].l = l, t[p].r = r; 11 if (l == r) { 12 read(t[p].minn); 13 t[p].tag = 0; 14 return; 15 } 16 int mid = (l + r) >> 1; 17 Build(l, mid, ls(p)); 18 Build(mid + 1, r, rs(p)); 19 t[p].minn = min(t[ls(p)].minn, t[rs(p)].minn); 20 } 21 22 void Push_down(int p) { 23 if (t[p].tag) { 24 t[ls(p)].minn += t[p].tag; 25 t[rs(p)].minn += t[p].tag; 26 t[ls(p)].tag += t[p].tag; 27 t[rs(p)].tag += t[p].tag; 28 t[p].tag = 0; 29 } 30 } 31 32 void Modify(int l, int r, int p, int k) { 33 if (l <= t[p].l && t[p].r <= r) { 34 t[p].minn += k; 35 t[p].tag += k; 36 return; 37 } 38 Push_down(p); 39 int mid = (t[p].l + t[p].r) >> 1; 40 if (l <= mid) Modify(l, r, ls(p), k); 41 if (mid < r) Modify(l, r, rs(p), k); 42 t[p].minn = min(t[ls(p)].minn, t[rs(p)].minn); 43 } 44 45 int main() { 46 read(n), read(m); 47 Build(1, n, 1); 48 rep(i, 1, m) { 49 int cnt, l, r; 50 read(cnt), read(l), read(r); 51 Modify(l, r, 1, -cnt); 52 if (t[1].minn < 0) { 53 writeln(-1); 54 writeln(i); 55 return 0; 56 } 57 } 58 writeln(0); 59 return 0; 60 }