【CH4301】Can you answer on these queries III

这是一道用线段树维护区间最大子段和的题目

本题的关键在于如何维护区间最大子段和。对于线段树的每一个节点,我们定义四个域:sum,l,r,maxx分别表示这个区间的和、以这个区间左边为起点的最大子段和是多少、以这个区间右边为起点的最大子段和是多少、这个区间的最大子段和是多少。当我们用这个区间的两个子区间合并他的时候,就会有如下结论:

  1. a[now].sum=a[now<<1].sum+a[now<<1|1].sum;
  2. a[now].l=max(a[now<<1].l,a[now<<1].sum+a[now<<1|1].l);
  3. a[now].r=max(a[now<<1|1].r,a[now<<1|1].sum+a[now<<1].r);
  4. a[now].maxx=max(max(a[now<<1].maxx,a[now<<1|1].maxx),a[now<<1].r+a[now<<1|1].l);

有了这个,这道题就容易多了,本题为单点修改,将难度降低了一下,用线段树按照上述步骤处理即可。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 int n,m;
 8 struct node {
 9     int sum,l,r,maxx;
10 }a[500010<<2];
11 inline int read() {
12     int ret=0;
13     int op=1;
14     char c=getchar();
15     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
16     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
17     return ret*op;
18 }
19 inline void pushup(int now) {
20     a[now].sum=a[now<<1].sum+a[now<<1|1].sum;
21     a[now].l=max(a[now<<1].l,a[now<<1].sum+a[now<<1|1].l);
22     a[now].r=max(a[now<<1|1].r,a[now<<1|1].sum+a[now<<1].r);
23     a[now].maxx=max(max(a[now<<1].maxx,a[now<<1|1].maxx),a[now<<1].r+a[now<<1|1].l);
24 }
25 void build(int now,int l,int r) {
26     if(l==r) {
27         a[now].l=a[now].r=a[now].maxx=a[now].sum=read();
28         return ;
29     }
30     int mid=l+r>>1;
31     build(now<<1,l,mid);
32     build(now<<1|1,mid+1,r);
33     pushup(now);
34 }
35 void updata(int now,int l,int r,int x,int val) {
36     if(l==r&&x==l) {
37         a[now].l=a[now].r=a[now].maxx=a[now].sum=val;
38         return ;
39     }
40     int mid=l+r>>1;
41     if(x<=mid) updata(now<<1,l,mid,x,val);
42     else updata(now<<1|1,mid+1,r,x,val);
43     pushup(now);
44 }
45 node query(int now,int l,int r,int x,int y) {
46     if(x<=l&&r<=y) return a[now];
47     int mid=l+r>>1;
48     if(y<=mid) return query(now<<1,l,mid,x,y);
49     else if(x>mid) return query(now<<1|1,mid+1,r,x,y);
50     node ret;
51     node reta=query(now<<1,l,mid,x,y);
52     node retb=query(now<<1|1,mid+1,r,x,y);
53     ret.sum=reta.sum+retb.sum;
54     ret.l=max(reta.l,reta.sum+retb.l);
55     ret.r=max(retb.r,retb.sum+reta.r);
56     ret.maxx=max(max(reta.maxx,retb.maxx),reta.r+retb.l);
57     return ret;
58 }
59 int main() {
60     n=read(); m=read();
61     build(1,1,n);
62     while(m--) {
63         int op=read(),x=read(),y=read();
64         if(op==2) {
65             updata(1,1,n,x,y);
66         }
67         else {
68             if(x>y) swap(x,y);
69             printf("%d\n",query(1,1,n,x,y).maxx);
70         }
71     }
72     return 0;
73 }
AC Code

 

posted @ 2019-05-25 00:19  AD_shl  阅读(474)  评论(0编辑  收藏  举报