TZOJ 4021 Ugly Problem(线段树区间子段最大)

描述

给定一个序列A[0],A[1],…A[N-1],要求找到p0,p1,p2,p3使得A[p0]+A[p0+1]+…+A[p1] + A[p2]+A[p2+1]+…+A[p3]最大(0<=p0<=p1<p2<=p3<N)。你只需要求出这个最大值就可以。

输入

输入的第一行为一个数N(2<=N<=10000),接下来的一行为N个整数(-100<A[i]<100)。

输出

输出一个整数表示最大值。

样例输入

5
-1 -2 -4 -5 4

样例输出

3

题意

如上。

题解

枚举分割点,求左区间最大子段和和到右区间最大字段和。

区间最大值段和是一个经典题,线段树维护。

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=10005;
 4 struct node{
 5     int sum,lmax,rmax,lrs; 
 6 }tree[maxn<<2];
 7 void pushup(int x){
 8     tree[x].sum=tree[x<<1].sum+tree[x<<1|1].sum;
 9     tree[x].lmax=max(tree[x<<1].lmax,tree[x<<1|1].lmax+tree[x<<1].sum);
10     tree[x].rmax=max(tree[x<<1|1].rmax,tree[x<<1].rmax+tree[x<<1|1].sum);
11     tree[x].lrs=max(max(tree[x<<1].lrs,tree[x<<1|1].lrs),tree[x<<1].rmax+tree[x<<1|1].lmax);
12 }
13 void build(int l,int r,int p){
14     if(l==r){
15         scanf("%d",&tree[p].sum);
16         tree[p].lmax=tree[p].lrs=tree[p].rmax=tree[p].sum;
17         return;
18     }
19     int mid=(l+r)>>1;
20     build(l,mid,p<<1);
21     build(mid+1,r,p<<1|1);
22     pushup(p);
23 }
24 void update(int k,int v,int l,int r,int p){
25     if(l==r){
26         tree[p].lmax=tree[p].lrs=tree[p].rmax=tree[p].sum=v;
27         return;
28     }
29     int mid=(l+r)>>1;
30     if(k<=mid)update(k,v,l,mid,p<<1);
31     else update(k,v,mid+1,r,p<<1|1);
32     pushup(p);
33 }
34 node quert(int L,int R,int l,int r,int p){
35     if(L<=l&&r<=R)return tree[p];
36     int mid=(l+r)>>1;
37     node vis,f1,f2;
38     vis.sum=0;
39     if(L<=mid)vis=f1=quert(L,R,l,mid,p<<1);
40     if(R>mid)vis=f2=quert(L,R,mid+1,r,p<<1|1);
41     if(L<=mid&&R>mid){
42         vis.sum=f1.sum+f2.sum;
43         vis.lmax=max(f1.lmax,f1.sum+f2.lmax);
44         vis.rmax=max(f2.rmax,f2.sum+f1.rmax);
45         vis.lrs=max(max(f1.lrs,f2.lrs),f1.rmax+f2.lmax);
46     }
47     return vis;
48 }
49 int main(){
50     int n,maxx=-1e9;
51     scanf("%d",&n);
52     build(1,n,1);
53     for(int i=1;i<n;i++)
54         maxx=max(quert(1,i,1,n,1).lrs+quert(i+1,n,1,n,1).lrs,maxx);
55     printf("%d\n",maxx);
56     return 0;
57 }

posted on 2019-10-08 20:09  大桃桃  阅读(116)  评论(0编辑  收藏  举报

导航