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
  • 相关阅读:
    go语言圣经第8章Goroutines 和 Channels
    VSCODE远程开发 golang环境配置
    golang排序简述
    go语言圣经第七章笔记-接口
    Java并发编程小记
    [Effective Modern C++] Item 7. Distinguish between () and {} when creating objects
    [Effective Modern C++] Item 6. Use the explicitly typed initializer idiom when auto deduces undesired types
    [Effective Modern C++] Item 5. Prefer auto to explicit type declarations
    [Effective Modern C++] Item 4. Know how to view deduced types
    [Effective Modern C++] Item 3. Understand decltype
  • 原文地址:https://www.cnblogs.com/shl-blog/p/10920913.html
Copyright © 2011-2022 走看看