zoukankan      html  css  js  c++  java
  • [洛谷P4513][题解]小白逛公园

    0.前言

    水题解使我快乐~

    1.题目概述

    动态维护最大子段和。

    2.题解

    首先一看到修改和区间查询→线段树です!
    但是这个题需要维护的东西比普通的线段树多亿一点,我们来一步步讲。
    首先,题目里都说了查询最大子段和,我们用一个mx代表。
    其次,如何更新mx
    容易发现,一个区间的最大子段和总共只有三种情况:在左边取、在右边取和左右各取一部分。
    前两种好说,但第三种需要多维护一些东西。
    易知,答案区间一定占了左边的右半部分和右边的左半部分(还不是很绕
    前缀和+后缀和
    所以把区间内最大前缀和与最大后缀和统计出来即可。

    3.代码

    #define N 500010
    int n,m,num[N];
    struct Node {
    	int l,r,wei,mx,lmx,rmx;
    	Node(){l=r=wei=mx=lmx=rmx=0;}
    	Node(int _l,int _r,int _w,int _m,int _lm,int _rm){
    		l=_l,r=_r,wei=_w,mx=_m,lmx=_lm,rmx=_rm;
    	}
    }tr[N<<2];
    inline void Pushup(int k){
    	tr[k].wei=tr[ls].wei+tr[rs].wei;
    	tr[k].lmx=max(tr[ls].lmx,tr[ls].wei+tr[rs].lmx);
    	tr[k].rmx=max(tr[ls].rmx+tr[rs].wei,tr[rs].rmx);
    	tr[k].mx=max(max(tr[ls].mx,tr[rs].mx),tr[ls].rmx+tr[rs].lmx);
    }
    void Build(int k,int l,int r){
    	tr[k].l=l,tr[k].r=r;
    	if(l==r){
    		tr[k].wei=tr[k].lmx=tr[k].rmx=tr[k].mx=num[l];
    		return;
    	}
    	Build(ls,l,nmid);
    	Build(rs,nmid+1,r);
    	Pushup(k);
    }
    void Modify(int k,int pos,int val){
    	if(tr[k].l==tr[k].r){
    		tr[k].wei=tr[k].lmx=tr[k].rmx=tr[k].mx=val;
    		return;
    	}
    	if(pos<=tmid)Modify(ls,pos,val);
    	else Modify(rs,pos,val);
    	Pushup(k);
    }
    Node Query(int k,int l,int r){
    	if(l<=tr[k].l&&tr[k].r<=r)return tr[k];
    	if(r<=tmid)return Query(ls,l,r);
    	else if(tmid<l)return Query(rs,l,r);
    	else {
    		Node ll=Query(ls,l,r),rr=Query(rs,l,r),res;
    		res=Node(l,r,ll.wei+rr.wei,0,max(ll.lmx,ll.wei+rr.lmx),max(rr.rmx,rr.wei+ll.rmx));
    		res.mx=max(max(ll.mx,rr.mx),ll.rmx+rr.lmx);
    		return res; 
    	}
    }
    int main(){
    	Read(n),Read(m);
    	for(rg int i=1;i<=n;i++)Read(num[i]);
    	Build(1,1,n);
    	while(m--){
    		int k,ap,bs;
    		Read(k),Read(ap),Read(bs);
    		if(k==1){
    			if(ap>bs)swap(ap,bs);
    			Node res=Query(1,ap,bs);
    			cout<<res.mx<<endl;
    		}else Modify(1,ap,bs);
    	}
    	return 0;
    }
    

    lmx,rmx即为前缀和与后缀和。

    4.完结撒花

    总觉得这题讲过做过来着……déjà vu?

  • 相关阅读:
    【转帖】Explorer参数详解
    获取html页面时如何选择合适的Encoding
    不要在wpf窗口类的构造函数中抛异常
    把FlvDownloader重构了一下
    VK Cup 2012 Qualification Round 1 A. Next Round
    迎接2012新赛季——HDOJ系列热身赛(2) Problem A HDU 4161 Iterated Difference
    青蛙过河~~~~
    VK Cup 2012 Qualification Round 1 D. Ice Sculptures
    HDU 1006 Tick and Tick
    ACM参赛总结
  • 原文地址:https://www.cnblogs.com/juruoajh/p/13386404.html
Copyright © 2011-2022 走看看