标签:data namespace out str space 难点 void spoj arc
GSS系列是非常好的线段树、树链剖分练手题目,这道题是最简单的了
题意:求区间最大子段和
显然这道题我们用线段树来解决,难点在于维护最大前缀和以及最大后缀和
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int n,m,cnt,a[5000000]; 5 struct SegmentTree { 6 int l,r,pre,suf,data,sum; 7 }; 8 SegmentTree tree[5000000],s; 9 inline void build(int l,int r,int k) { 10 tree[k].l=l; 11 tree[k].r=r; 12 if(l==r) { 13 tree[k].pre=tree[k].suf=tree[k].data=tree[k].sum=a[l]; 14 return; 15 } 16 int mid=(l+r)/2; 17 build(l,mid,2*k); 18 build(mid+1,r,2*k+1); 19 tree[k].data=max(tree[2*k].data,tree[2*k+1].data); 20 tree[k].data=max(tree[k].data,tree[2*k].suf+tree[2*k+1].pre); 21 tree[k].pre=max(tree[2*k].pre,tree[2*k].sum+tree[2*k+1].pre); 22 tree[k].suf=max(tree[2*k].suf+tree[2*k+1].sum,tree[2*k+1].suf); 23 tree[k].sum=tree[2*k].sum+tree[2*k+1].sum; //建线段树 24 } 25 inline void search(int l,int r,int k) { 26 if(l<=tree[k].l&&r>=tree[k].r) { 27 if(cnt==0) { 28 cnt=1; 29 s=tree[k]; 30 } else { 31 s.pre=max(s.pre,s.sum+tree[k].pre); 32 s.sum=s.sum+tree[k].sum; 33 s.data=max(s.data,tree[k].data); 34 s.data=max(s.data,s.suf+tree[k].pre); 35 s.suf=max(tree[k].suf,s.suf+tree[k].sum); 36 } 37 return; 38 } 39 int mid=(tree[k].l+tree[k].r)/2; 40 if(l<=mid) search(l,r,2*k); 41 if(r>mid) search(l,r,2*k+1);//前缀和 42 } 43 int main() { 44 cin>>n; 45 for(int i=1;i<=n;i++) cin>>a[i]; 46 build(1,n,1); 47 int x,y; 48 cin>>m; 49 for(int i=1;i<=m;i++) { 50 cin>>x>>y; 51 cnt=0; 52 search(x,y,1); 53 cout<<s.data; 54 putchar(‘\n‘); 55 } 56 return 0; 57 }
标签:data namespace out str space 难点 void spoj arc
原文地址:https://www.cnblogs.com/modifY-blog/p/11337081.html