zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x43线段树 单点修改+查询区间最大子段和

    题目链接:https://www.acwing.com/problem/content/246/

    线段树合并线段的时候要更新结点中的ans值,但是这个值的更新依赖于lmax与rmax,这两个值的更新又依赖于sum,故查询的时候需要返回的是一个结点,返回代表的区间的信息。

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int maxn = 500010;
    const int inf=0x3f3f3f3f;
    int n,m;
    struct node{
        int l,r,s,lx,rx,ans;
    }t[maxn*4];
    void pushup(int rt){
        t[rt].lx=max(t[rt<<1].lx,t[rt<<1].s+t[rt<<1|1].lx);
        t[rt].rx=max(t[rt<<1|1].rx,t[rt<<1|1].s+t[rt<<1].rx);
        t[rt].s=t[rt<<1].s+t[rt<<1|1].s;
        t[rt].ans=max(max(t[rt<<1].ans,t[rt<<1|1].ans),t[rt<<1].rx+t[rt<<1|1].lx);
    }
    void build(int rt,int l,int r){
        t[rt].l=l;
        t[rt].r=r;
        if(l==r){
            scanf("%d",&t[rt].ans);
            t[rt].lx=t[rt].rx=t[rt].s=t[rt].ans;
            return ;
        }
        int mid=l+r>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        pushup(rt);
    }
    void update(int rt,int pos,int C){
        if(t[rt].l==t[rt].r){
            t[rt].s=t[rt].lx=t[rt].rx=t[rt].ans=C;
            return;
        }
        int mid=(t[rt].l+t[rt].r)>>1;
        if(pos<=mid) update(rt<<1,pos,C);
        else update(rt<<1|1,pos,C);
        pushup(rt);
    }
    node query(int rt,int L,int R){
        if(t[rt].l>=L && t[rt].r<=R){
            return t[rt];
        }
        node ans1,ans2;
        int mid=(t[rt].l+t[rt].r)>>1;
        if(L<=mid && R>mid){
            ans1=query(rt<<1,L,R);
            ans2=query(rt<<1|1,L,R);
            node ans;
            ans.s=ans1.s+ans2.s;
            ans.lx=max(ans1.lx,ans1.s+ans2.lx);
            ans.rx=max(ans2.rx,ans2.s+ans1.rx);
            ans.ans=max(max(ans1.ans,ans2.ans),ans1.rx+ans2.lx);
            return ans;
        }else if(L>mid){
            return query(rt<<1|1,L,R);
        }else if(R<=mid){
            return query(rt<<1,L,R);
        }
    }
    int main(){
        cin>>n>>m;
        build(1,1,n);
        while(m--){
            int t,x,y;
            scanf("%d%d%d",&t,&x,&y);
            if(t==1){
                if(x>y)swap(x,y);
                printf("%d
    ",query(1,x,y).ans);
            }else if(t==2){
                update(1,x,y);
            }
        }
        return 0;
    }
  • 相关阅读:
    SpringBoot启动配置原理
    SpringBoot和web开发
    SpringBoot和日志
    SpringBoot入门
    Docker仓库
    Docker Swarm
    Docker相关概念
    Docker服务编排
    Dockerfile
    Docker应用部署
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13297168.html
Copyright © 2011-2022 走看看