洛谷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 }

 

转载于:https://www.cnblogs.com/AlphaWA/p/10586075.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷P1168题目是关于中位数线段树解法的问题。中位数线段树解法可以通过维护两个堆来实现。一个是大根堆,一个是小根堆。每次插入元素时,根据一定的规则来维护这两个堆,使得大根堆的个数在一定情况下比小根堆多1或者相等。大根堆的最后一个元素即为中位数。具体的规则如下: 1. 如果大根堆和小根堆的个数相等,下一次插入的元素一定插入到大根堆。此时判断小根堆的堆顶是否大于当前元素x,如果是,则将小根堆的堆顶元素插入到大根堆,然后将x压入小根堆;否则直接将x压入大根堆。 2. 如果大根堆和小根堆的个数不相等,按照类似的规则进行操作。 通过以上规则,可以实现在每次插入元素时,维护两个堆的平衡,并且保证大根堆的最后一个元素即为中位数。 这种解法的时间复杂度为O(logN),其中N为序列的长度。 #### 引用[.reference_title] - *1* *2* [中位数(洛谷p1168)(堆/树状数组+二分/线段树+二分)](https://blog.csdn.net/qq_45604735/article/details/114382762)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [洛谷 P1168 中位数(权值线段树,离散化)](https://blog.csdn.net/qq_38232157/article/details/127594230)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值