洛谷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;
}