1. 程式人生 > >[SP1043]GSS1 - Can you answer these queries I

[SP1043]GSS1 - Can you answer these queries I

struct answer str == 線段 return shu lib n)

求區間內最大非空子段和,沒什麽可說的吧。

線段樹,每個區間維護從左端開始的最大非空子段和,區間內的最大非空子段和,以右端結束的最大非空子段和,還有區間和。

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......

[SP1043]GSS1 - Can you answer these queries I