CODEVS 3981(求最大子段和+线段树)
题目链接:http://codevs.cn/problem/3981/
参考:https://blog.csdn.net/jokingcoder/article/details/81477253
一个区间的最大子段和有三种情况:
1.等于这个区间左儿子的最大子段和
2.等于这个区间右儿子的最大子段和
3.等于这个区间左儿子的后缀最大子段和+右儿子的前缀最大子段和
tree[k].sumax = max(max(tree[l].sumax,tree[r].sumax),tree[l].rmax + tree[r].lmax);
一个区间前缀最大子段和有两种情况:
1.等于这个区间左儿子的前缀最大子段和
2.等于这个这儿子的前缀和加上右儿子的前缀最大子段和
tree[k].lmax = max(tree[l].lmax,tree[l].sum + tree[r].lmax);
同样
一个区间的后缀最大子段和有两种情况:
1.等于这个区间右儿子的后缀最大子段和
2.等于这个区间右儿子的后缀和+左儿子的最大后缀和
tree[k].rmax = max(tree[r].rmax,tree[r].sum + tree[l].rmax);
1 #include <iostream> 2 #include <cstring> 3 #define mem(a,b) memset(a,b,sizeof(a)); 4 using namespace std; 5 typedef long long ll; 6 const int maxn = 500005; 7 const ll INF = 0x3f3f3f3f; 8 ll n,q,a[maxn]; 9 struct node{ 10 ll sum,sumax,lmax,rmax; 11 }tree[maxn]; 12 void pushup(ll k) { 13 ll l = k << 1, r = k << 1 | 1; 14 tree[k].sum = tree[l].sum + tree[r].sum; 15 tree[k].sumax = max(max(tree[l].sumax,tree[r].sumax),tree[l].rmax + tree[r].lmax); 16 tree[k].lmax = max(tree[l].lmax,tree[l].sum + tree[r].lmax); 17 tree[k].rmax = max(tree[r].rmax,tree[r].sum + tree[l].rmax); 18 } 19 void build(ll k,ll l,ll r) { 20 if(l == r) { 21 tree[k].lmax = tree[k].rmax = tree[k].sum = tree[k].sumax = a[l]; 22 return ; 23 } 24 ll mid = (l + r) >> 1; 25 build(k << 1, l, mid); 26 build(k << 1 | 1,mid + 1, r); 27 pushup(k); 28 } 29 node Search(ll l,ll r,ll L,ll R,ll k) { 30 if(L <= l&& R >= r) { 31 return tree[k]; 32 } 33 ll mid = (l + r) >> 1,ld = k << 1, rd = k << 1 | 1; 34 if(R <= mid) return Search(l,mid,L,R,ld); 35 if(L > mid) return Search(mid+1,r,L,R,rd); 36 node lo = Search(l,mid,L,R,ld), ro = Search(mid+1,r,L,R,rd),ans; 37 ans.sum = lo.sum + ro.sum; 38 ans.sumax = max(max(lo.sumax,ro.sumax),lo.rmax+ro.lmax); 39 ans.lmax = max(lo.lmax,lo.sum+ro.lmax); 40 ans.rmax = max(ro.rmax,ro.sum+lo.rmax); 41 return ans; 42 } 43 int main() 44 { 45 cin >> n; 46 for(ll i = 1; i <= n; i++) { 47 cin >> a[i]; 48 } 49 build(1,1,n); 50 cin >> q; 51 ll x,y; 52 for(ll i = 1; i <= q; i++) { 53 cin >> x >> y; 54 cout << Search(1,n,x,y,1).sumax << endl; 55 } 56 return 0; 57 }