洛谷1083(差分+二分 or 线段树)

第一种方法:可以二分最大天数订单的答案然后通过差分求一下是否可行。

 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 }

猜你喜欢

转载自www.cnblogs.com/AlphaWA/p/10586075.html