spoj 1557 GSS3 - Can you answer these queries III 线段树

题目链接

给出n个数, 2种操作, 一种是将第x个数改为y, 第二种是询问区间[x,y]内的最大连续子区间。

开4个数组, 一个是区间和, 一个是区间最大值, 一个是后缀的最大值, 一个是前缀的最大值。 合并起来好麻烦......

  1 #include <iostream>
  2 #include <vector>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <map>
  7 #include <set>
  8 #include <string>
  9 #include <queue>
 10 using namespace std;
 11 #define pb(x) push_back(x)
 12 #define ll long long
 13 #define mk(x, y) make_pair(x, y)
 14 #define lson l, m, rt<<1
 15 #define mem(a) memset(a, 0, sizeof(a))
 16 #define rson m+1, r, rt<<1|1
 17 #define mem1(a) memset(a, -1, sizeof(a))
 18 #define mem2(a) memset(a, 0x3f, sizeof(a))
 19 #define rep(i, a, n) for(int i = a; i<n; i++)
 20 #define ull unsigned long long
 21 typedef pair<int, int> pll;
 22 const double eps = 1e-8;
 23 const int mod = 1e9+7;
 24 const int inf = 1061109567;
 25 const int maxn = 5e4+5;
 26 int sum[maxn<<2], suf_max[maxn<<2], pre_max[maxn<<2], maxx[maxn<<2];
 27 void pushUp(int rt) {
 28     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
 29     suf_max[rt] = max(suf_max[rt<<1|1], suf_max[rt<<1]+sum[rt<<1|1]);
 30     pre_max[rt] = max(pre_max[rt<<1], pre_max[rt<<1|1]+sum[rt<<1]);
 31     maxx[rt] = max(maxx[rt<<1], maxx[rt<<1|1]);
 32     maxx[rt] = max(maxx[rt], suf_max[rt<<1]+pre_max[rt<<1|1]);
 33 }
 34 void build(int l, int r, int rt) {
 35     if(l == r) {
 36         scanf("%d", &maxx[rt]);
 37         sum[rt] = pre_max[rt] = suf_max[rt] = maxx[rt];
 38         return ;
 39     }
 40     int m = l+r>>1;
 41     build(lson);
 42     build(rson);
 43     pushUp(rt);
 44 }
 45 void update(int p, int val, int l, int r, int rt) {
 46     if(l == r) {
 47         sum[rt] = pre_max[rt] = suf_max[rt] = maxx[rt] = val;
 48         return ;
 49     }
 50     int m = l+r>>1;
 51     if(p<=m)
 52         update(p, val, lson);
 53     else
 54         update(p, val, rson);
 55     pushUp(rt);
 56 }
 57 int query_sum(int L, int R, int l, int r, int rt) {
 58     if(L<=l&&R>=r) {
 59         return sum[rt];
 60     }
 61     int m = l+r>>1, ret = 0;
 62     if(L<=m)
 63         ret += query_sum(L, R, lson);
 64     if(R>m)
 65         ret += query_sum(L, R, rson);
 66     return ret;
 67 }
 68 int query_suf(int L, int R, int l, int r, int rt) {
 69     if(L<=l&&R>=r) {
 70         return suf_max[rt];
 71     }
 72     int m = l+r>>1;
 73     if(R<=m)
 74         return query_suf(L, R, lson);
 75     if(L>m)
 76         return query_suf(L, R, rson);
 77     return max(query_suf(L, m, lson)+query_sum(m+1, R, rson), query_suf(m+1, R, rson));
 78 }
 79 int query_pre(int L, int R, int l, int r, int rt) {
 80     if(L<=l&&R>=r) {
 81         return pre_max[rt];
 82     }
 83     int m = l+r>>1;
 84     if(R<=m)
 85         return query_pre(L, R, lson);
 86     if(L>m)
 87         return query_pre(L, R, rson);
 88     return max(query_pre(L, m, lson), query_pre(m+1, R, rson)+query_sum(L, m, lson));
 89 }
 90 int query(int L, int R, int l, int r, int rt) {
 91     if(L<=l&&R>=r) {
 92         return maxx[rt];
 93     }
 94     int m = l+r>>1;
 95     if(R<=m)
 96         return query(L, R, lson);
 97     if(L>m)
 98         return query(L, R, rson);
 99     return max(max(query(L, m, lson), query(m+1, R, rson)), query_pre(m+1, R, rson)+query_suf(L, m, lson));
100 }
101 int main()
102 {
103     int n, q, x, y, sign;
104     scanf("%d", &n);
105     build(1, n, 1);
106     scanf("%d", &q);
107     while(q--) {
108         scanf("%d%d%d", &sign, &x, &y);
109         if(sign)
110             printf("%d\n", query(x, y, 1, n, 1));
111         else
112             update(x, y, 1, n, 1);
113     }
114     return 0;
115 }

 

转载于:https://www.cnblogs.com/yohaha/p/5024355.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值