zoukankan      html  css  js  c++  java
  • 【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
    ",query(1,1,n,x,y).maxx);
    70         }
    71     }
    72     return 0;
    73 }
    AC Code
  • 相关阅读:
    docker 安装redis
    docker安装mongodb
    最强NBA
    在IDEA中配置RunDashboard
    【给每个人的摄影史33】普通人如何通过摄影史提升拍摄水平:长线学习的建议
    【给每个人的摄影史32】普通人如何通过摄影史提升拍摄水平:拍摄层面的提示
    【给每个人的摄影史31】普通人如何通过摄影史提升拍摄水平:意识上的提示
    【给每个人的摄影史30】普通人如何通过摄影史提升拍摄水*:再次回顾摄影史
    【给每个人的摄影史29】通过读画册培养摄影眼
    【给每个人的摄影史27】用照片表达观念艺术:作为照片的观念艺术
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10920913.html
Copyright © 2011-2022 走看看