求区间内最大非空子段和,没什么可说的吧。
线段树,每个区间维护从左端开始的最大非空子段和,区间内的最大非空子段和,以右端结束的最大非空子段和,还有区间和。
pushup()的写法要注意,不要漏掉任何一种情况。
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6 inline int read(){ 7 int x=0,f=1;char ch=getchar(); 8 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 9 while(ch>=‘0‘&&ch<=‘9‘){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();} 10 return x*f; 11 } 12 const int MAXN=50005; 13 int n,m,a[MAXN],ql,qr; 14 struct Node{ 15 int L,M,R,S; 16 }b[MAXN*4]; 17 #define mid ((l+r)>>1) 18 #define lc (o<<1) 19 #define rc ((o<<1)|1) 20 Node mer(Node x,Node y){ 21 Node ans; 22 ans.L=max(x.L,x.S+y.L); 23 ans.M=max(x.M,max(y.M,x.R+y.L)); 24 ans.R=max(x.R+y.S,y.R); 25 ans.S=x.S+y.S; 26 return ans; 27 } 28 void pushup(int o){ 29 b[o]=mer(b[lc],b[rc]); 30 } 31 void build(int o,int l,int r){ 32 if(l==r){ 33 b[o].L=b[o].M=b[o].R=b[o].S=a[l]; 34 return; 35 } 36 build(lc,l,mid); 37 build(rc,mid+1,r); 38 pushup(o); 39 } 40 Node query(int o,int l,int r){ 41 if(ql<=l&&r<=qr) return b[o]; 42 if(ql>mid) return query(rc,mid+1,r); 43 else if(qr<=mid) return query(lc,l,mid); 44 else return mer(query(lc,l,mid),query(rc,mid+1,r)); 45 } 46 int main(){ 47 n=read(); 48 for(int i=1;i<=n;i++) 49 a[i]=read(); 50 build(1,1,n); 51 m=read(); 52 while(m--){ 53 ql=read(),qr=read(); 54 printf("%d\n",query(1,1,n).M); 55 } 56 return 0; 57 }
说起来我一开始把题看成求区间最大值了233......
原文地址:https://www.cnblogs.com/ErkkiErkko/p/9275307.html
时间: 2024-11-12 23:37:57