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

    题目背景

    小新经常陪小白去公园玩,也就是所谓的遛狗啦…

    题目描述

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

    一开始,小白就根据公园的风景给每个公园打了分-.-。小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第 aaa 个和第 bbb 个公园之间(包括 aaa 、 bbb 两个公园)选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。同时,由于一些公园的景观会有所改变,所以,小白的打分也可能会有一些变化。

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

    输入输出格式

    输入格式:

    第一行,两个整数 NNN 和 MMM ,分别表示表示公园的数量和操作(遛狗或者改变打分)总数。
    接下来 NNN 行,每行一个整数,依次给出小白 开始时对公园的打分。
    接下来 MMM 行,每行三个整数。第一个整数 KKK , 111 或 222 。

    • K=1K=1K=1 表示,小新要带小白出去玩,接下来的两个整数 aaa 和 bbb 给出了选择公园的范围( 1≤a,b≤N1≤a,b≤N1a,bN );
    • K=2K=2K=2 表示,小白改变了对某个公园的打分,接下来的两个整数 ppp 和 sss ,表示小白对第 ppp 个公园的打分变成了 sss ( 1≤p≤N1≤p≤N1pN )。
      其中, 1≤N≤5000001≤N≤500 0001N500000 , 1≤M≤1000001≤M≤100 0001M100000 ,所有打分都是绝对值不超过 100010001000 的整数。
    输出格式:

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

    输入输出样例

    输入样例#1: 
    5 3
    1 2 -3 4 5
    1 2 3
    2 2 -1
    1 2 3
    输出样例#1: 
    2
    -1

    Solution:

      本题实在是鬼~~(善用结构体啊!又是调半天不出来的题~

      经典的带修改的区间最大连续子段和问题,典型的线段树嘛~!

      写了一个数组版线段树,不知道查询怎么去维护了,最后还是借鉴别人的代码,学了一波结构体写线段树的风格。

      建一棵线段树维护一下信息:$lmx$(与左边界相连的最大连续子段和),$rmx$(与右端点相连的最大连续子段和),$all$(整个区间的最大连续子段和),$sum$(整个区间的和)。

      那么还是正常的单点修改,只不过每次$pushup$自下而上维护节点$rt$的信息时,需要这些操作:

      1、当左儿子$ls$的$rmx$和右儿子$rs$的$lmx$均为$<0$时,整个区间的最大连续子段和$rt.all$直接取$Max(rs.lmx,ls.rmx)$。否则$rt.all$加上左右儿子中不为负值的$ls.rmx,rs.lmx$,然后$rt.all$再与单独的$ls.all$和$rs.all$中取最大值。

      2、当前节点$rt$的与左端点相连的最大连续子段和,在左儿子$ls.lmx$和右儿子$rs.lmx+ls.sum$中取最大值。

      3、同理当前节点$rt$的与右端点相连的最大连续子段和,在右儿子$rs.rmx$和左儿子$ls.rmx+rs.sum$中取最大值。

      4、不要忘了维护整个区间的和,$rt.sum=ls.sum+rs.sum$。

      (注意$pushup$函数的变量为结构体,左右儿子定义为$const node &ls$和$const node &rs$,因为查询时不能确定一段区间的最大连续子段和,所以需要想$pushup$函数一样更新一下整个区间的信息,定义变量为结构体能方便后面查询维护区间最大子段和,加$const$是因为$ls,rs$本身也是个变量)

      再讲下写的吐血的查询(注意坑点,区间可能$l>r$),整个递归过程参考了神犇的代码(这个结构体的递归写的太美妙了~!),首先将一段区间分为多个小区间,当区间包含时直接返回当前区间,然后每次递归向上用$pushup$维护整段查询的区间,引入一个结构体变量$a$记录整段区间的值。最后输出的是返回结构体变量的成员$all$(即该区间的最大连续子段和)。

      (写完此题,又“深度”理解了一波线段树~唉~太菜了`~)

    代码:

    #include<bits/stdc++.h>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define il inline
    #define ll long long
    #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
    #define Max(a,b) ((a)>(b)?(a):(b))
    using namespace std;
    const int N=500005;
    int n,m;
    struct node{
        ll sum,lmx,rmx,all;    
    }t[N<<2];
    il int gi(){
        int a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-')x=getchar();
        if(x=='-')x=getchar(),f=1;
        while(x>='0'&&x<='9')a=(a<<3)+(a<<1)+x-48,x=getchar();
        return f?-a:a;
    }
    il void pushup(node &rt,const node &ls,const node &rs){
        if(ls.rmx<0&&rs.lmx<0)rt.all=Max(ls.rmx,rs.lmx);
        else {
            rt.all=0;
            if(ls.rmx>0)rt.all+=ls.rmx;
            if(rs.lmx>0)rt.all+=rs.lmx;
        }
        rt.all=Max(rt.all,Max(ls.all,rs.all));
        rt.lmx=Max(ls.lmx,ls.sum+rs.lmx);
        rt.rmx=Max(rs.rmx,rs.sum+ls.rmx);
        rt.sum=ls.sum+rs.sum;
    }
    il void build(int l,int r,int rt){
        if(l==r){t[rt].all=t[rt].sum=t[rt].lmx=t[rt].rmx=gi();return;}
        int m=l+r>>1;
        build(lson),build(rson);
        pushup(t[rt],t[rt<<1],t[rt<<1|1]);
    }
    il void update(int L,int c,int l,int r,int rt){
        if(l==r){t[rt].all=t[rt].sum=t[rt].lmx=t[rt].rmx=c;return;}
        int m=l+r>>1;
        if(L<=m)update(L,c,lson);
        else update(L,c,rson);
        pushup(t[rt],t[rt<<1],t[rt<<1|1]);
    }
    il node query(int L,int R,int l,int r,int rt){
        if(L<=l&&R>=r)return t[rt];
        int m=l+r>>1;
        if(L<=m&&R>m){node a;pushup(a,query(L,R,lson),query(L,R,rson));return a;}
        else if(L<=m)return query(L,R,lson);
        return query(L,R,rson);
    }
    int main(){
        n=gi(),m=gi();
        build(1,n,1);
        int k,x,y,c;
        while(m--){
            k=gi();
            if(k==1){x=gi(),y=gi();if(x>y)swap(x,y);printf("%lld
    ",query(x,y,1,n,1).all);}
            else {x=gi(),c=gi(),update(x,c,1,n,1);}
        }
        return 0;
    }
  • 相关阅读:
    数组初始化
    排序算法
    fast rcnn,faster rcnn使用cudann加速问题
    「不啰嗦」和「说清楚」-20141223早读课
    加州理工学院公开课:机器学习与数据挖掘_Regularization(第十二课)
    2014年百度之星程序设计大赛
    一个伟大的发现,装X一下。笔记本win7系统64位机器执行unity 时,屏幕模糊解决的方法
    面向对象基础——类与对象的定义
    hdu1325 Is It A Tree?(二叉树的推断)
    持续集成(CI)工具------Hudson/Jenkins(Continuous Integration)安装与配置具体解释
  • 原文地址:https://www.cnblogs.com/five20/p/9074309.html
Copyright © 2011-2022 走看看