http://poj.org/problem?id=2750
之前做过类似的题 把一段的左连续最大、最小 右连续最大及最小及中间的连续更新出 就可以算出这段最大的连续和
注意不能全部加上 加上一特判 如果最大和是全部数的和就减去这段最小的和
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 using namespace std; 7 #define N 100010 8 struct node 9 { 10 int va,lmax,rmin,lmin,rmax,smax,smin; 11 }p[N<<2]; 12 void pushup(int w) 13 { 14 p[w].va = p[w<<1].va+p[w<<1|1].va; 15 p[w].lmax = max(p[w<<1].lmax,p[w<<1].va+p[w<<1|1].lmax); 16 p[w].lmin = min(p[w<<1].lmin,p[w<<1].va+p[w<<1|1].lmin); 17 p[w].rmax = max(p[w<<1|1].rmax,p[w<<1|1].va+p[w<<1].rmax); 18 p[w].rmin = min(p[w<<1|1].rmin,p[w<<1|1].va+p[w<<1].rmin); 19 p[w].smax = max(max(p[w].lmax,p[w].rmax),max(p[w<<1].smax,p[w<<1|1].smax)); 20 p[w].smax = max(p[w].smax,p[w<<1].rmax+p[w<<1|1].lmax); 21 p[w].smin = min(min(p[w].lmin,p[w].rmin),min(p[w<<1].smin,p[w<<1|1].smin)); 22 p[w].smin = min(p[w].smin,p[w<<1].rmin+p[w<<1|1].lmin); 23 } 24 void build(int l,int r,int w) 25 { 26 if(l==r) 27 { 28 scanf("%d",&p[w].va); 29 p[w].lmax=p[w].lmin=p[w].rmax=p[w].rmin=p[w].smax=p[w].smin=p[w].va; 30 return ; 31 } 32 int m = (l+r)>>1; 33 build(l,m,w<<1); 34 build(m+1,r,w<<1|1); 35 pushup(w); 36 } 37 void update(int pp,int d,int l,int r,int w) 38 { 39 if(l==r) 40 { 41 p[w].va = d; 42 p[w].lmax=p[w].lmin=p[w].rmax=p[w].rmin=p[w].smax=p[w].smin=p[w].va; 43 return ; 44 } 45 int m = (l+r)>>1; 46 if(pp<=m) 47 update(pp,d,l,m,w<<1); 48 else 49 update(pp,d,m+1,r,w<<1|1); 50 pushup(w); 51 } 52 int main() 53 { 54 int n,m,a,b,i; 55 while(cin>>n) 56 { 57 build(1,n,1); 58 cin>>m; 59 while(m--) 60 { 61 scanf("%d%d",&a,&b); 62 update(a,b,1,n,1); 63 if(p[1].smax==p[1].va) 64 cout<<p[1].smax-p[1].smin<<endl; 65 else 66 cout<<max(p[1].smax,p[1].va-p[1].smin)<<endl; 67 } 68 } 69 return 0; 70 }