To find the maximal continuous sub-sequence of an interval, the basic idea is to divide, the sequence may be in the left half of the interval, may also be in the right half of the interval, it may be across the midpoint of the interval, this is the maximum suffix of the left dial hand interval plus the maximum prefix of the right sub-range.
Segment Tree Maintenance Three information: Interval maximum prefix, maximum suffix, the maximum continuous sub-range subscript.
The maximum prefix can be obtained by recursion: either the maximum prefix of the left dial hand interval, or the maximum prefix of the left dial hand interval, plus the right sub-interval, and
The maximum suffix is similar to recursion.
The prefix and the entire sequence to be preprocessed before recursion.
1#include <cstdio>2#include <cstring>3#include <algorithm>4 #defineMP Make_pair5 #defineLCH (o) (o*2)6 #defineRCH (o) (o*2+1)7 using namespacestd;8 9typedefLong LongLL;Tentypedef pair<int,int>Interval; One Const intMAXN =500000+Ten; A Const intMaxnode =1000000+Ten; - - LL PREFIX_SUM[MAXN]; the -LL sum (intAintb) {returnPREFIX_SUM[B]-prefix_sum[a-1]; } - -LL sum (Interval p) {returnsum (P.first, P.second);} + - Interval Better (Interval A, Interval b) + { A if(SUM (a)! = SUM (b))returnSUM (a) > sum (b)?a:b; at returnA < b? A:B;//pair comes with a dictionary order - } - - intQL, QR;//Query Interval - - structIntervaltree in { - intMax_prefix[maxnode], Max_suffix[maxnode]; to Interval Max_sub[maxnode]; + - voidBuildintOintLintR) the { * if(L = = R) {Max_prefix[o] = max_suffix[o] = L; Max_sub[o] =MP (L, L);} $ ElsePanax Notoginseng { - intM = (L + R) >>1; the intLC = LCH (o), rc =RCH (o); + Build (LC, L, M); ABuild (RC, m+1, R); the + //recursive Max_prefix -LL V1 =sum (L, MAX_PREFIX[LC]); $LL v2 =sum (L, MAX_PREFIX[RC]); $ if(V1 = = v2) Max_prefix[o] =min (MAX_PREFIX[LC], MAX_PREFIX[RC]); - ElseMax_prefix[o] = v1 > v2?MAX_PREFIX[LC]: MAX_PREFIX[RC]; - the //recursive Max_suffix -V1 =sum (MAX_SUFFIX[LC], R);WuyiV2 =sum (MAX_SUFFIX[RC], R); the if(V1 = = v2) Max_suffix[o] =min (MAX_SUFFIX[LC], MAX_SUFFIX[RC]); - ElseMax_suffix[o] = v1 > v2?MAX_SUFFIX[LC]: MAX_SUFFIX[RC]; Wu - //recursive max_sub AboutMax_sub[o] =better (MAX_SUB[LC], MAX_SUB[RC]); $Max_sub[o] =better (Max_sub[o], MP (MAX_SUFFIX[LC], MAX_PREFIX[RC])); - } - } - AInterval Query_prefix (intOintLintR) + { the if(Max_prefix[o] <= QR)returnMP (L, Max_prefix[o]); - intM = (L + R) >>1; $ intLC = LCH (o), rc =RCH (o); the if(QR <= M)returnQuery_prefix (LC, L, M); theInterval i = Query_prefix (RC, m+1, R); theI.first =L; the returnbetter (i, MP (L, MAX_PREFIX[LC])); - } in theInterval Query_suffix (intOintLintR) the { About if(Max_suffix[o] >= QL)returnMP (Max_suffix[o], R); the intM = (L + R) >>1; the intLC = LCH (o), rc =RCH (o); the if(QL > M)returnQuery_suffix (RC, m+1, R); +Interval i =Query_suffix (LC, L, M); -I.second =R; the returnbetter (i, MP (MAX_SUFFIX[RC], R));Bayi } the theInterval Query (intOintLintR) - { - if(QL <= L && R <= QR)returnMax_sub[o]; the intM = (L + R) >>1; the intLC = LCH (o), rc =RCH (o); the if(QR <= M)returnQuery (LC, L, M); the if(QL > M)returnQuery (RC, m+1, R); -Interval I1 = Query_suffix (LC, L, M);//maximum suffix of the left dial hand interval theInterval i2 = Query_prefix (RC, m+1, R);//maximum prefix for right sub-range theInterval i3 = Better (query (LC, L, M), query (RC, m+1, R));//maximum continuous and two sub-intervals the returnbetter (i3, MP (I1.first, I2.second));94 } the }tree; the the intMain ()98 { About //freopen ("In.txt", "R", stdin); - 101 intKase =0, N, a, Q;102 while(SCANF ("%d%d", &n, &q) = =2)103 {104prefix_sum[0] =0; the for(inti =1; I <= N; i++) {scanf ("%d", &a); Prefix_sum[i] = prefix_sum[i-1] +A;}106Tree.build (1,1, n);107printf"Case %d:\n", ++Kase);108 while(q--)109 { the intL, R;111scanf"%d%d", &l, &R); theQL = L; QR =R;113Interval ans = tree.query (1,1, n); theprintf"%d%d\n", Ans.first, ans.second); the } the }117 118 return 0;119}
code June
UVa 1400 (segment tree) "Ray, Pass me the dishes!"