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;
}

猜你喜欢

转载自blog.csdn.net/leo_nasir/article/details/80517708