码迷,mamicode.com
首页 > 其他好文 > 详细

$SP1716$ $GSS3$ $-$ $Can$ $you$ $answer$ $these$ $queries$ $III$

时间:2019-08-08 23:15:05      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:using   比较   turn   class   lag   details   printf   题意   print   

链接

背景

\(Bin\) \(Jin\)\(2007.8.3\)\(SP\) \(1716\)

题意

给定一个数列,要求单点修改、区间查询最大子段和。

解法

线段树模板。维护每个区间和 \(sum\) 、区间最大子段和 \(val\) 、区间从左端点开始向右的最大子段和 \(lmax\) 、区间从右端点开始向左的最大子段和 \(rmax\)

\(trick\)

查询时先加入一个节点,后来查询到的节点直接与该节点比较更新即可。

细节

\(1.\) 建树和修改时各个信息均要赋值。(好傻逼的错误啊)

\(2.\) 查询中比较更新式注意各信息顺序,修改时要用到别的信息值的先更新。

代码

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int ret=0,f=1;
    char ch=getchar();
    while(ch>'9'||ch<'0')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ret=(ret<<1)+(ret<<3)+ch-'0';
        ch=getchar();
    }
    return ret*f;
}
int n,q,a[50005],op,x,val,l,r,ans;
bool flag;
struct SegmentTree
{
    int l;
    int r;
    int val;
    int sum;
    int lmax;
    int rmax;
}t[200005],tmp;
void build(int pos,int l,int r)
{
    t[pos].l=l;
    t[pos].r=r;
    if(l==r)
    {
        t[pos].sum=a[l];
        t[pos].lmax=a[l];
        t[pos].rmax=a[l];
        t[pos].val=a[l];
        return;
    }
    int mid=(l+r)>>1;
    build(pos<<1,l,mid);
    build(pos<<1|1,mid+1,r);
    t[pos].sum=t[pos<<1].sum+t[pos<<1|1].sum;
    t[pos].lmax=max(t[pos<<1].lmax,t[pos<<1].sum+t[pos<<1|1].lmax);
    t[pos].rmax=max(t[pos<<1|1].rmax,t[pos<<1].rmax+t[pos<<1|1].sum);
    t[pos].val=max(max(t[pos<<1].val,t[pos<<1|1].val),t[pos<<1].rmax+t[pos<<1|1].lmax);
}
void modify(int pos,int x,int val)
{
    if(t[pos].l==t[pos].r)
    {
        t[pos].sum=val;
        t[pos].lmax=val;
        t[pos].rmax=val;
        t[pos].val=val;
        return;
    }
    int mid=(t[pos].l+t[pos].r)>>1;
    if(x<=mid)
        modify(pos<<1,x,val);
    else
        modify(pos<<1|1,x,val);
    t[pos].sum=t[pos<<1].sum+t[pos<<1|1].sum;
    t[pos].lmax=max(t[pos<<1].lmax,t[pos<<1].sum+t[pos<<1|1].lmax);
    t[pos].rmax=max(t[pos<<1|1].rmax,t[pos<<1].rmax+t[pos<<1|1].sum);
    t[pos].val=max(max(t[pos<<1].val,t[pos<<1|1].val),t[pos<<1].rmax+t[pos<<1|1].lmax);
}
void query(int pos,int l,int r)
{
    if(t[pos].l>=l&&t[pos].r<=r)
    {
        if(!flag)
        {
            flag=1;
            tmp=t[pos];
        }
        else
        {
            tmp.lmax=max(tmp.lmax,tmp.sum+t[pos].lmax);
            tmp.sum=tmp.sum+t[pos].sum;
            tmp.val=max(max(tmp.val,t[pos].val),tmp.rmax+t[pos].lmax);
            tmp.rmax=max(t[pos].rmax,tmp.rmax+t[pos].sum);
        }
        return;
    }
    int mid=(t[pos].l+t[pos].r)>>1;
    if(l<=mid)
        query(pos<<1,l,r);
    if(r>mid)
        query(pos<<1|1,l,r);
}
int main()
{
    n=read();
    for(register int i=1;i<=n;i++)
        a[i]=read();
    build(1,1,n);
    q=read();
    while(q--)
    {
        op=read();
        if(!op)
        {
            x=read();
            val=read();
            modify(1,x,val);
        }
        else
        {
            l=read();
            r=read();
            flag=0;
            query(1,l,r);
            printf("%d\n",tmp.val);
        }
    }
    return 0;
}

$SP1716$ $GSS3$ $-$ $Can$ $you$ $answer$ $these$ $queries$ $III$

标签:using   比较   turn   class   lag   details   printf   题意   print   

原文地址:https://www.cnblogs.com/Peter0701/p/11324258.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!