Acer.MoOi之路

一只蒟蒻

线段树[模板]最大连续子段和以及单节点修改 洛谷SP1716 GSS3 - Can you answer these queries III

//SegmenTree
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int M=200500;
struct Tree
{
    int bond[2];
    int lazy;
    int son[2];
    int sum;
    int mks[3];
}tree[M];
int n,m,root=0,cnt=1;
int num[M];
int ans,que;
void pushup(int x)//更新节点 
{
    int lson=tree[x].son[0];
    int rson=tree[x].son[1];
    tree[x].mks[0]=max(tree[lson].mks[0],tree[lson].sum+tree[rson].mks[0]);
    tree[x].mks[1]=max(tree[rson].mks[1],tree[rson].sum+tree[lson].mks[1]);
    tree[x].mks[2]=max(tree[rson].mks[0]+tree[lson].mks[1],max(tree[lson].mks[2],tree[rson].mks[2]));
    tree[x].sum=tree[lson].sum+tree[rson].sum;
    tree[x].bond[0]=tree[lson].bond[0];
    tree[x].bond[1]=tree[rson].bond[1];
    return ; 
}
void change(int poi,int val,int cur)
{
    if (tree[cur].bond[0]==tree[cur].bond[1])
    {
        tree[cur].sum=val;
        tree[cur].mks[2]=tree[cur].mks[1]=tree[cur].mks[0]=val; 
        return ;
    }
    int mid=(tree[cur].bond[0]+tree[cur].bond[1])>>1;
    if (poi<=mid) change(poi,val,tree[cur].son[0]);
    else change(poi,val,tree[cur].son[1]);
    pushup(cur);
    return ;
}
void built(int L,int R,int cur)
{
    if (L==R)
    {
        tree[cur].son[0]=tree[cur].son[1]=-1;
        tree[cur].bond[0]=tree[cur].bond[1]=L;
        tree[cur].sum=num[L];
        tree[cur].mks[0]=tree[cur].mks[1]=tree[cur].mks[2]=num[R];
        tree[cur].lazy=0;
        return ;
    }
    int mid=(L+R)>>1;
    tree[cur].son[0]=cnt++;
    tree[cur].son[1]=cnt++;
    built(L,mid,tree[cur].son[0]);
    built(mid+1,R,tree[cur].son[1]);
    pushup(cur);
    return ;
}
void query(int L,int R,int cur)
{
    if (L<=tree[cur].bond[0]&&tree[cur].bond[1]<=R)
    {
        ans=max(ans,max(tree[cur].mks[2],tree[cur].mks[0]+que));
        que=max(que+tree[cur].sum,tree[cur].mks[1]);
        return ;
    }
    int mid=(tree[cur].bond[0]+tree[cur].bond[1])>>1;
    if (L<=mid) query(L,R,tree[cur].son[0]);
    if (R>mid) query(L,R,tree[cur].son[1]);
    return ;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
        scanf("%d",&num[i]);
    built(1,n,root);
    scanf("%d",&m);
    while (m--)
    {
        int flag,l,r;
        scanf("%d %d %d",&flag,&l,&r);
        if (flag)
        {
            ans=-1e9;
            que=ans;
            query(l,r,root);
            cout<<ans<<endl;
        }
        else change(l,r,root);
    }
    return 0;
}

阅读更多
版权声明: https://blog.csdn.net/ACerAndAKer/article/details/80688457
个人分类: 数据结构-线段树
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭