洛谷P4513 小白逛公园

题链

题意求区间最长连续子序列最大和

当数据存在负数时,不能单纯取三个地方的max,如:

p[rt].maxn = max(p[ls].rmax+p[rs].lmax,max(p[rt].lmax,p[rt].rmax));
#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#pragma GCC optimize("O2")
using namespace std;
#define LL long long
#define ll long long
#define ULL unsigned long long
#define ls rt<<1
#define rs rt<<1|1
#define one first
#define two second
#define MS 500009
#define INF 1e18
#define mod 99999997
#define Pi acos(-1.0)
#define Pair pair<LL,LL>
#define eps 1e-9

LL n,m,k;
struct node{
	LL sum;
	LL lmax,rmax;
	LL maxn;
}p[MS<<2]; 

void push_up(int rt){
	p[rt].sum = p[ls].sum + p[rs].sum;
	p[rt].lmax = max(p[ls].lmax,p[ls].sum+p[rs].lmax);
	p[rt].rmax = max(p[rs].rmax,p[rs].sum+p[ls].rmax);
	
	//p[rt].maxn = max(p[ls].rmax+p[rs].lmax,max(p[rt].lmax,p[rt].rmax)); // 当数据存在负数时,该条不成立 
	
	/**************************************************/ // 将所有可能对maxn产生影响的都取最大 
	LL sidemax = max(p[rt].lmax,p[rt].rmax);
	LL midmax = max(p[ls].rmax,p[rs].lmax);
	LL lrmaxn = max(p[ls].maxn,p[rs].maxn);
	p[rt].maxn = max(sidemax,midmax);
	p[rt].maxn = max(p[rt].maxn,lrmaxn);
	p[rt].maxn = max(p[rt].maxn,p[ls].rmax+p[rs].lmax);
	/**************************************************/
}

void build(int l,int r,int rt){
	if(l == r){
		LL x;
		cin >> x;
		p[rt] = {x,x,x,x};
		return;
	}
	int m = l+r>>1;
	build(l,m,ls);
	build(m+1,r,rs);
	push_up(rt);
}

void update(int L,int R,int l,int r,int rt,LL val){
	if(L <= l && r <= R){
		p[rt] = {val,val,val,val};
		return;
	}
	int m = l+r>>1;
	if(m >= L) update(L,R,l,m,ls,val);
	if(m <  R) update(L,R,m+1,r,rs,val);
	push_up(rt);
}

node get_max(int L,int R,int l,int r,int rt){
	if(L <= l && r <= R){
		return p[rt];
	}
	int m = l+r>>1;
	node ans;
	if(L <= m && m < R){
		node t1 = get_max(L,R,l,m,ls);
		node t2 = get_max(L,R,m+1,r,rs);
		ans.lmax = max(t1.lmax,t1.sum+t2.lmax);
		ans.rmax = max(t2.rmax,t2.sum+t1.rmax);
		ans.sum = t1.sum + t2.sum;
		/**************************************************/ // 将所有可能对maxn产生影响的都取最大 
		LL sidemax = max(ans.lmax,ans.rmax);
		LL midmax = max(t1.rmax,t2.lmax);
		LL lrmax = max(t1.maxn,t2.maxn);
		ans.maxn = max(sidemax,midmax);
		ans.maxn = max(ans.maxn,lrmax);
		ans.maxn = max(ans.maxn,t1.rmax+t2.lmax);
		/**************************************************/
		return ans;
	}
	else if(m < L) return get_max(L,R,m+1,r,rs);
	else return get_max(L,R,l,m,ls); 
}

int main(){
	ios::sync_with_stdio(false);
	cin >> n >> m;
	build(1,n,1);
	while(m--){
		LL op,l,r,pos,tar;
		cin >> op;
		if(op == 1){
			cin >> l >> r;
			if(l > r) swap(l,r); // 不交换则会在 TLE 之前就会出现 MLE 
			node cc = get_max(l,r,1,n,1);
			cout << cc.maxn << endl;
		}
		else{
			cin >> pos >> tar;
			update(pos,pos,1,n,1,tar);
		}
	}
	
	

	return 0;
}
posted @ 2021-03-16 13:34  棉被sunlie  阅读(47)  评论(0)    收藏  举报