zoukankan      html  css  js  c++  java
  • BZOJ1756 小白逛公园

    BZOJ1756 小白逛公园

    题目描述

    在小新家附近有一条“公园路”,路的一边从南到北依次排着 n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了。

    一开始,小白就根据公园的风景给每个公园打了分-.-。小新为了省事,每次遛狗的时候都会事先规定一个范围,

    小白只可以选择第 a 个和第 b 个公园之间(包括 a 、 b 两个公园)选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。

    同时,由于一些公园的景观会有所改变,所以,小白的打分也可能会有一些变化。

    那么,就请你来帮小白选择公园吧。

    输入格式

    第一行,两个整数 N 和 M ,分别表示表示公园的数量和操作(遛狗或者改变打分)总数。

    接下来 N 行,每行一个整数,依次给出小白 开始时对公园的打分。
    接下来 M行,每行三个整数。第一个整数 K ,1 或 2 。

    • K=1 表示,小新要带小白出去玩,接下来的两个整数 a 和 b 给出了选择公园的范围( 1≤a,b≤N);
    • K=2 表示,小白改变了对某个公园的打分,接下来的两个整数 ps ,表示小白对第 p 个公园的打分变成了 s ( 1≤p≤N )。
      其中, 1≤N≤500 000 , 1≤M≤100 000 ,所有打分都是绝对值不超过 1000 的整数。

    输出格式

     小白每出去玩一次,都对应输出一行,只包含一个整数,表示小白可以选出的公园得分和的最大值。

    Solution

    显然的线段树。

    每个结点需要维护最大子段和,包含从左端点的最大子段和,包含右端点的最大子段和,然后讨论吧

    主要就是pushdown比较麻烦。

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN = 500000 + 10;
    typedef long long ll;
    
    inline ll read()
    {
        ll f=1,x=0;
        char ch;
        do
        {
            ch=getchar();
            if(ch=='-') f=-1;
        }while(ch<'0'||ch>'9');
        do
        {
            x=(x<<3)+(x<<1)+ch-'0';
            ch=getchar();
        }while(ch>='0'&&ch<='9');
        return f*x;
    }
    
    int n,m;
    int a[MAXN];
    
    struct node
    {
        int l,r;
        int lmax,rmax,sum,ans;
        inline int mid()
        {
            return (l+r)>>1;
        }
    };node tree[MAXN*4];
    
    #define lc o<<1
    #define rc o<<1|1
    
    inline void pushup(int o)
    {
        tree[o].sum=tree[lc].sum+tree[rc].sum;
        tree[o].lmax=max(tree[lc].lmax,tree[lc].sum+tree[rc].lmax);
        tree[o].rmax=max(tree[rc].rmax,tree[rc].sum+tree[lc].rmax);
        tree[o].ans=max(max(tree[lc].ans,tree[rc].ans),tree[lc].rmax+tree[rc].lmax);
        return;
    }
    
    inline void build(int o,int l,int r)
    {
        tree[o].l=l;tree[o].r=r;
        if(l==r)
        {
            tree[o].sum=a[l];
            tree[o].lmax=tree[o].rmax=tree[o].ans=a[l];
            return;
        }
        int mid=tree[o].mid();
        build(lc,l,mid);
        build(rc,mid+1,r);
        pushup(o);
    }
    
    inline void update(int o,int x,int y)
    {
        int l = tree[o].l,r=tree[o].r;
        if(l==r)
        {
            tree[o].sum=y;
            tree[o].lmax=tree[o].rmax=tree[o].ans=y;
            //cout<<l<<" "<<tree[o].sum<<endl;
            return;
        }
        int mid=tree[o].mid();
        if(x<=mid)
        update(lc,x,y);
        else
        update(rc,x,y);
        pushup(o);
    }
    
    inline node query(int o,int x,int y)
    {
        int l =tree[o].l,r=tree[o].r;
        if(l>=x&&r<=y) return tree[o];
        else
        {
            int mid = tree[o].mid();
            if(y<=mid) return query(lc,x,y);
            else if(x>mid) return query(rc,x,y);
            else
            {
                node t = query(lc,x,y);
                node t1 = query(rc,x,y);
                node now;
                now.lmax=max(t.lmax,t.sum+t1.lmax);
                now.rmax=max(t1.rmax,t1.sum+t.rmax);
                now.ans=max(max(t.ans,t1.ans),t.rmax+t1.lmax);
                return now;
            }
        }
    }
    
    int main()
    {
        n = read();m = read();
        for(int i=1;i<=n;i++)
            a[i]=read();
        build(1,1,n);
        for(int i=1;i<=m;i++)
        {
            int k=read(),x=read(),y=read();
            if(k==1)
            {
                if(x>y) swap(x,y);
                cout<<query(1,x,y).ans<<endl;
            }
            if(k==2)
            {
                update(1,x,y);
            }
        }
     } 

    然后update里脑抽写错一行,调了好久。。。

    inline void update(int o,int x,int y)
    {
        int l = tree[o].l,r=tree[o].r;
        if(l==r)
        {
            tree[o].sum=y;
            tree[o].lmax=tree[o].rmax=tree[o].ans=y;
            //cout<<l<<" "<<tree[o].sum<<endl;
            return;
        }
        int mid=tree[o].mid();
        if(x<=mid)
        build(lc,x,y);//??!
        else
        build(rc,x,y);//??!
        pushup(o);
    }

    我也不知道上面的代码我是怎么打出来的

  • 相关阅读:
    c# 改变FileUpload 上传文件大小
    使用ActiveX读取客户端mac地址
    javascript小技巧
    【2012百度之星/资格赛】H:用户请求中的品牌 [后缀数组]
    POJ1012 约瑟夫环问题[双向循环链表+打表技巧]
    北大ACM题分类
    ACM大量习题题库
    POJ1423 计算出n的阶乘的位数大数问题[Stirling公式]
    ACM训练计划(下)
    POJ2080 角度问题[cmath函数]
  • 原文地址:https://www.cnblogs.com/wlzs1432/p/9184679.html
Copyright © 2011-2022 走看看