【解题报告】小白逛公园 vijos

题目传送门

这道题是一道线段树的一个求一个连续最大字段和是一个区间线段树一个很妙妙的操作,这里后面我们后面就会提到,因为今天博主没有时间了所以先粘一篇代码供大家参考,其实代码理解还是非常的简单的。

代码如下:

#include<bits/stdc++.h>
using namespace std;
struct data{
    int rmax,lmax,maxtot,sum;
    int l,r,son[2];
}node[1010000];
int ini[501000];
int n,k;
int cnt=0;
void update(int k)
{
    node[k].sum=node[node[k].son[0]].sum+node[node[k].son[1]].sum;
    node[k].lmax=max(node[node[k].son[0]].lmax,node[node[k].son[0]].sum+node[node[k].son[1]].lmax);
    node[k].rmax=max(node[node[k].son[1]].rmax,node[node[k].son[1]].sum+node[node[k].son[0]].rmax);
    node[k].maxtot=max(node[node[k].son[0]].maxtot,node[node[k].son[1]].maxtot);
    node[k].maxtot=max(node[k].maxtot,node[node[k].son[0]].rmax+node[node[k].son[1]].lmax);
}
void Build_tree(int &k,int l,int r)
{
    cnt++;
    k=cnt;
    node[k].l=l;node[k].r=r;
    if(l==r)
    {
        node[k].sum=ini[l];node[k].lmax=ini[l];node[k].rmax=ini[l];node[k].maxtot=ini[l];return;
    }
    int mid=(l+r)/2;
    Build_tree(node[k].son[0],l,mid);
    Build_tree(node[k].son[1],mid+1,r);
    update(k);
}
void modify(int k,int goal,int val)
{
    if(node[k].l==node[k].r&&node[k].l==goal)
    {
        node[k].sum=val;node[k].lmax=val;node[k].rmax=val;node[k].maxtot=val;
    }
    else
    {
        int mid=(node[k].l+node[k].r)/2;
        if(mid>=goal)
        modify(node[k].son[0],goal,val);
        else
        {
            modify(node[k].son[1],goal,val);
        }
        update(k);
    }
}
data query(int k,int l,int r)
{
    if(node[k].l==l&&node[k].r==r)
    {
        return (data){node[k].rmax,node[k].lmax,node[k].maxtot,node[k].sum,0,0,0,0};
    }
    else
    {
        int mid=(node[k].l+node[k].r)/2;
        if(r<=mid) return query(node[k].son[0],l,r);
        if(l>mid)  return query(node[k].son[1],l,r);
        else
        {
            data d1=query(node[k].son[0],l,mid);
            data d2=query(node[k].son[1],mid+1,r);
            data ret;
            ret.sum=d1.sum+d2.sum;
            ret.lmax=max(d1.lmax,d1.sum+d2.lmax);
            ret.rmax=max(d2.rmax,d1.rmax+d2.sum);
            ret.maxtot=max(d1.maxtot,d2.maxtot);
            ret.maxtot=max(ret.maxtot,d1.rmax+d2.lmax);
            return ret;
        }
    }
}
int main()
{

    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&ini[i]);
    }
    int root=0;
    Build_tree(root,1,n);
    int a,b,c;
    for(int i=1;i<=k;++i)
    {
        scanf("%d%d%d",&a,&b,&c);
        if(a==2)
        {
            modify(1,b,c);
        }
        else
        {
            if(b>c)
            {int a;a=b;b=c;c=a;}
            cout<<query(1,b,c).maxtot<<endl;
        }
    }
    return 0;
}
posted @ 2018-04-21 16:52  Mudrobot  阅读(155)  评论(0编辑  收藏  举报