zoukankan      html  css  js  c++  java
  • 【解题报告】小白逛公园 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;
    }
  • 相关阅读:
    7月15日考试 题解(链表+状压DP+思维题)
    暑假集训日记
    C# .NET 使用 NPOI 生成 .xlsx 格式 Excel
    JavaSE 基础 第42节 局部内部类
    JavaSE 基础 第41节 匿名内部类
    JavaSE 基础 第40节 内部类概述
    JavaSE 基础 第39节 接口的应用
    JavaSE 基础 第38节 接口的实现
    JavaSE 基础 第37节 接口概述
    JavaSE 基础 第36节 抽象类概述与使用
  • 原文地址:https://www.cnblogs.com/mudrobot/p/9026921.html
Copyright © 2011-2022 走看看