luogu P4253 小白逛公園

題目在這裏呀~

題意

1、單點修改
2、求區間[l,r]內的最大子序列

題解

做法還算好想吧(如果做過類似題目
比如poj 的 hotel ?好像沒什麼差別的。
就是一棵線段樹每個節點要記四個值:左端點連續的和最大值,右端點連續的和的最大值,區間和,區間最大子序列和。
注意點:
1、在求和時因爲這個詢問區間是拼起來的,所以在query時返回最好是結構體,以便合併。(不用的話不知道怎麼做qwq)
2、pushup中左端點的連續和最大值爲左兒子的連續和最大值或者左兒子的和+右兒子的左端點連續和最大值,其他也是一個道理。
大概就這兩點是比較重要的吧tat(有時間就寫一下哦~)

//Suplex
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define N 2000000
#define Segment_tree ST
using namespace std;
int n,m,opt,x,y;

struct ST{
    int mx,s,ls,rs;
}t[N+N+N+N];

inline void pushup(ST &rt,ST lson,ST rson)
{
    if(lson.rs<0 && rson.ls<0) rt.mx=max(lson.rs,rson.ls);
    else{
        rt.mx=0;
        if(lson.rs>0) rt.mx=lson.rs;
        if(rson.ls>0) rt.mx+=rson.ls;
    }
    rt.mx=max(rt.mx,max(lson.mx,rson.mx));
    rt.ls=max(lson.ls,lson.s+rson.ls);
    rt.rs=max(rson.rs,rson.s+lson.rs);
    rt.s=lson.s+rson.s;
}

void build(int rt,int l,int r)
{
    if(l==r){
        scanf("%d",&t[rt].mx);
        t[rt].s=t[rt].ls=t[rt].rs=t[rt].mx;
        return;
    }
    int mid=(l+r)>>1;
    build(rt+rt,l,mid);
    build(rt+rt+1,mid+1,r);
    pushup(t[rt],t[rt+rt],t[rt+rt+1]);
}

void modify(int rt,int l,int r,int x,int delta)
{
    if(l==r){
        t[rt].s=t[rt].ls=t[rt].rs=t[rt].mx=delta;
        return;
    }
    int mid=(l+r)>>1;
    if(x<=mid) modify(rt+rt,l,mid,x,delta);
    else modify(rt+rt+1,mid+1,r,x,delta);
    pushup(t[rt],t[rt+rt],t[rt+rt+1]);
}

ST query(int rt,int l,int r,int x,int y)
{
    if(x<=l && r<=y) return t[rt];
    int mid=(l+r)>>1;
    if(y<=mid) return query(rt+rt,l,mid,x,y);
    else if(x>mid) return query(rt+rt+1,mid+1,r,x,y);
    else{
        ST tmp,lson=query(rt+rt,l,mid,x,mid),rson=query(rt+rt+1,mid+1,r,mid+1,y);
        pushup(tmp,lson,rson);
        return tmp;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    build(1,1,n);
    while(m--){
        scanf("%d%d%d",&opt,&x,&y);
        if(opt==1){
            if(x>y) swap(x,y);
            printf("%d\n",query(1,1,n,x,y).mx);
        }else modify(1,1,n,x,y);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章