From e66cb3d823ed386df481d0ee755a9a7b9a0959cb Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Sun, 15 Nov 2015 00:01:06 -0500 Subject: [PATCH 01/14] Make segment tree multifunctional. The reference code for the segment tree can now store different types of data, depending on what is specified as the type in the SegmentTreeType variable 'type'. Using the helper function in segment tree operations automatically handles returning the appropriate data to store in the nodes of the tree. --- structures/segment-tree/segment-tree.cpp | 108 +++++++++++++++++------ 1 file changed, 83 insertions(+), 25 deletions(-) diff --git a/structures/segment-tree/segment-tree.cpp b/structures/segment-tree/segment-tree.cpp index 5878b1a..3f3ac7a 100644 --- a/structures/segment-tree/segment-tree.cpp +++ b/structures/segment-tree/segment-tree.cpp @@ -2,8 +2,29 @@ #include using namespace std; +// dummy query returns; modify as necessary +#define ST_QUERY_DUMMY_MAX 99999999 +#define ST_QUERY_DUMMY_MIN -99999999 +#define ST_QUERY_DUMMY_SUM 0 + +// choose information to store +enum SegmentTreeType { ST_MIN, ST_MAX, ST_SUM }; +const SegmentTreeType type = ST_MIN; + // number of entries in array -unsigned int N; +unsigned int N = 10; + +int segment_tree_helper(const int a, const int b) +{ + if(type == ST_MIN) + return (a < b ? a : b); + else if(type == ST_MAX) + return (a > b ? a : b); + else if(type == ST_SUM) + return (a + b); + else + return -1; +} int build_segment_tree(int* const data, const unsigned int start, const unsigned int end, int* const tree, const unsigned int st_idx) { @@ -17,56 +38,81 @@ int build_segment_tree(int* const data, const unsigned int start, const unsigned const int left = build_segment_tree(data, start, mid, tree, (2 * st_idx) + 1); const int right = build_segment_tree(data, mid + 1, end, tree, (2 * st_idx) + 2); - if(left > right) tree[st_idx] = left; - else tree[st_idx] = right; + tree[st_idx] = segment_tree_helper(left, right); return tree[st_idx]; } -void update_segment_tree(int* const tree, const unsigned int start, const unsigned int end, const unsigned int changed_idx, const int new_val, const unsigned int st_idx) +void update_segment_tree(int* const tree, const unsigned int start, const unsigned int end, const unsigned int changed_idx, const int old_val, const int new_val, const unsigned int st_idx) { if(changed_idx < start || changed_idx > end) return; - if(new_val > tree[st_idx] || start == end) - tree[st_idx] = new_val; + if(type == ST_MIN) + { + if(new_val < tree[st_idx] || start == end) + tree[st_idx] = new_val; + } + else if(type == ST_MAX) + { + if(new_val > tree[st_idx] || start == end) + tree[st_idx] = new_val; + } + else if(type == ST_SUM) + { + int delta = new_val - old_val; + tree[st_idx] += delta; + } + if(start == end) return; const unsigned int mid = start + ((end - start) / 2); - update_segment_tree(tree, start, mid, changed_idx, new_val, (2 * st_idx) + 1); - update_segment_tree(tree, mid + 1, end, changed_idx, new_val, (2 * st_idx) + 2); + update_segment_tree(tree, start, mid, changed_idx, old_val, new_val, (2 * st_idx) + 1); + update_segment_tree(tree, mid + 1, end, changed_idx, old_val, new_val, (2 * st_idx) + 2); return; } -int query_segment_tree(const int* const tree, const unsigned int start, const unsigned int end, const unsigned int range_start, const unsigned int range_end, int greatest, const unsigned int st_idx) +int query_segment_tree(const int* const tree, const unsigned int start, const unsigned int end, const unsigned int range_start, const unsigned int range_end, int val, const unsigned int st_idx) { if(start > range_end || end < range_start) - return -2; + { + if(type == ST_MIN) + return ST_QUERY_DUMMY_MAX; + else if(type == ST_MAX) + return ST_QUERY_DUMMY_MIN; + else if(type == ST_SUM) + return ST_QUERY_DUMMY_SUM; + } if(start == end) return tree[st_idx]; - if(start >= range_start && end <= range_end) + if(type == ST_MIN && (start >= range_start && end <= range_end)) + { + if(tree[st_idx] < val) + return tree[st_idx]; + } + else if(type == ST_MAX && (start >= range_start && end <= range_end)) { - if(tree[st_idx] > greatest) + if(tree[st_idx] > val) return tree[st_idx]; } + else if(type == ST_SUM && (start >= range_start && end <= range_end)) + { + return tree[st_idx]; + } else { const unsigned int mid = start + ((end - start) / 2); - const int left = query_segment_tree(tree, start, mid, range_start, range_end, greatest, (2 * st_idx) + 1); - const int right = query_segment_tree(tree, mid + 1, end, range_start, range_end, greatest, (2 * st_idx) + 2); - - if(left > greatest) - greatest = left; - if(right > greatest) - greatest = right; + const int left = query_segment_tree(tree, start, mid, range_start, range_end, val, (2 * st_idx) + 1); + const int right = query_segment_tree(tree, mid + 1, end, range_start, range_end, val, (2 * st_idx) + 2); + val = segment_tree_helper(left, right); } - return greatest; + return val; } int main() @@ -80,11 +126,23 @@ int main() build_segment_tree(src_array, 0, N - 1, segtree, 0); // update value in segtree - src_array[42] = 43; - update_segment_tree(segtree, 0, N - 1, 42, 43, 0); - - // query segtree between indices 0 and 12, inclusive - int result = query_segment_tree(segtree, 0, N - 1, 0, 12, -1, 0); + int old = src_array[4]; + src_array[4] = 43; + update_segment_tree(segtree, 0, N - 1, 4, old, 43, 0); + old = src_array[2]; + src_array[2] = 21; + update_segment_tree(segtree, 0, N - 1, 2, old, 21, 0); + old = src_array[3]; + src_array[3] = 2; + update_segment_tree(segtree, 0, N - 1, 3, old, 2, 0); + old = src_array[9]; + src_array[9] = 1; + update_segment_tree(segtree, 0, N - 1, 9, old, 1, 0); + + // query segtree between indices 0 and 9, inclusive + int result = query_segment_tree(segtree, 0, N - 1, 0, 9, ST_QUERY_DUMMY_MAX, 0); + + cout << result << endl; delete[] segtree; From a34e174357f7a37128ad5a123e8371d52d9ca01f Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Sun, 15 Nov 2015 12:08:18 -0500 Subject: [PATCH 02/14] Move function documentation inside block. --- .../coming-and-going/coming-and-going.cpp | 82 +++++++++++-------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp b/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp index a4b0d22..311f825 100644 --- a/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp +++ b/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp @@ -9,17 +9,19 @@ using namespace std; // #endif const unsigned int N = 14; -// #ifdef hackpackpp -// build the segment tree -// -// data - source array to build segment tree from -// start - the start index of the array (should be 0) -// end - the end index of the array (size - 1) -// tree - the array to hold the segment tree sized appropriately -// st_idx - the current index of the segment tree (should be 0 when first called) -// #endif int build_segment_tree(int* const data, const unsigned int start, const unsigned int end, int* const tree, const unsigned int st_idx) { + // #ifdef hackpackpp + // build the segment tree from source data + // + // data - source array to build the segment tree from + // start - the start index of the array (should be 0 when first called) + // end - the end index of the array (size - 1) + // tree - the array to hold the segment tree, sized appropriately + // st_idx - the current index of the segment tree (should be 0 when first called) + // #endif + // #ifdef hackpackpp + // #ifdef hackpackpp // if start == end, this is a leaf node and should // have the original value from the array here @@ -56,24 +58,31 @@ int build_segment_tree(int* const data, const unsigned int start, const unsigned return tree[st_idx]; } -// #ifdef hackpackpp -// update a value in the segment tree -// -// to support range sums, this function would have to be modified to recurse -// down the tree to the leaf node before changing values; after the leaf node -// is updated, the new value should be passed back as a return value and each -// parent should update the sum they have by re-adding the values from the -// two children it has -// -// tree - the segment tree with values to be updated -// start - the start index of the _source_ array (should be 0) -// end - the end index of the _source_ array (size - 1) -// changed_idx - the index of the element that changed -// new_val - the new value of the element at changed_idx -// st_idx - the current index of the segment tree (should be 0 when first called) -// #endif + void update_segment_tree(int* const tree, const unsigned int start, const unsigned int end, const unsigned int changed_idx, const int new_val, const unsigned int st_idx) { + // #ifdef hackpackpp + // update a value in the segment tree + // + + // To support range sums, this function would have to be modified to recurse + // down the tree to the leaf node before changing values. After the leaf node + // is updated, the new value should be passed back as a return value and each + // parent should update the sum they have by re-adding the values from the + // two children it has. + // + // Alternatively, the old value (or at least some delta) could be an additional + // argument passed in during the original call. Nodes could update to their new + // respective values without waiting for children to report sums back. + // + // tree - the segment tree with values to be updated + // start - the start index of the _source_ array (should be 0) + // end - the end index of the _source_ array (size - 1) + // changed_idx - the index of the element that changed + // new_val - the new value of the element at changed_idx + // st_idx - the current index of the segment tree (should be 0 when first called) + // #endif + // #ifdef hackpackpp // out of range; should not be counted // #endif @@ -102,19 +111,20 @@ void update_segment_tree(int* const tree, const unsigned int start, const unsign return; } -// #ifdef hackpackpp -// find the largest value for a range -// -// tree - the segment tree to query -// start - the start index of the _source_ array -// end - the end index of the _source_ array -// range_start - the start index of the query -// range_end - the end index of the query -// greatest - the greatest value found so far (set to zero when first calling) -// st_idx - the current index in the segtree (set to zero when first calling) -// #endif int query_segment_tree(const int* const tree, const unsigned int start, const unsigned int end, const unsigned int range_start, const unsigned int range_end, int greatest, const unsigned int st_idx) { + // #ifdef hackpackpp + // find the largest value for a range + // + // tree - the segment tree to query + // start - the start index of the _source_ array + // end - the end index of the _source_ array + // range_start - the start index of the query + // range_end - the end index of the query + // greatest - the greatest value found so far (set to zero when first calling) + // st_idx - the current index in the segtree (set to zero when first calling) + // #endif + // #ifdef hackpackpp // out of range; do not continue // #endif From b1f733281535254337758ee988cdb4b4c0337180 Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Sun, 15 Nov 2015 12:20:54 -0500 Subject: [PATCH 03/14] Correct array visual. --- structures/segment-tree/source-array.eps | 130 +++++++++++------------ 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/structures/segment-tree/source-array.eps b/structures/segment-tree/source-array.eps index 5d18c16..9af76ee 100644 --- a/structures/segment-tree/source-array.eps +++ b/structures/segment-tree/source-array.eps @@ -1,9 +1,9 @@ %!PS-Adobe-3.0 EPSF-3.0 %%Creator: Ipelib 70108 (Ipe 7.1.8) -%%CreationDate: D:20151111205857 +%%CreationDate: D:20151115121935 %%LanguageLevel: 2 -%%BoundingBox: 7 775 265 841 -%%HiResBoundingBox: 7.6 775.6 264.4 840.168 +%%BoundingBox: 7 775 249 833 +%%HiResBoundingBox: 7.6 775.6 248.4 832.168 %%DocumentSuppliedResources: font DHOPVM+CMR12 %%EndComments %%BeginProlog @@ -357,8 +357,8 @@ cleartomark 0 J 1 j q 120 792 m 120 776 l -264 776 l -264 792 l +248 776 l +248 792 l h 0.678 0.847 0.902 rg q f* Q 0.4 w 0 g S @@ -387,7 +387,7 @@ h 0.745 g q f* Q 0.4 w 0 g S Q -q 1 0 0 1 100.874 827.714 cm 1 0 0 1 0 0 cm 0 g +q 1 0 0 1 92.874 819.714 cm 1 0 0 1 0 0 cm 0 g 0 G 1 0 0 1 0 -784.296 cm BT @@ -398,7 +398,7 @@ BT 0 G ET Q -q 1 0 0 1 116.653 827.968 cm 1 0 0 1 0 0 cm 0 g +q 1 0 0 1 108.653 819.968 cm 1 0 0 1 0 0 cm 0 g 0 G 1 0 0 1 0 -784.296 cm BT @@ -409,7 +409,7 @@ BT 0 G ET Q -q 1 0 0 1 132.896 828.119 cm 1 0 0 1 0 0 cm 0 g +q 1 0 0 1 124.896 820.119 cm 1 0 0 1 0 0 cm 0 g 0 G 1 0 0 1 0 -784.296 cm BT @@ -420,7 +420,7 @@ BT 0 G ET Q -q 1 0 0 1 148.896 827.818 cm 1 0 0 1 0 0 cm 0 g +q 1 0 0 1 140.896 819.818 cm 1 0 0 1 0 0 cm 0 g 0 G 1 0 0 1 0 -784.296 cm BT @@ -431,7 +431,7 @@ BT 0 G ET Q -q 1 0 0 1 164.989 827.968 cm 1 0 0 1 0 0 cm 0 g +q 1 0 0 1 156.989 819.968 cm 1 0 0 1 0 0 cm 0 g 0 G 1 0 0 1 0 -784.296 cm BT @@ -442,36 +442,30 @@ BT 0 G ET Q -q 95.6587 839.968 m -95.6587 823.968 l -175.659 823.968 l -175.659 839.968 l +q 87.6587 831.968 m +87.6587 815.968 l +167.659 815.968 l +167.659 831.968 l h 0.4 w S Q -q 111.659 839.968 m -111.659 823.968 l -111.659 823.968 l -111.659 823.968 l +q 103.659 831.968 m +103.659 815.968 l +103.659 815.968 l +103.659 815.968 l 0.4 w S Q -q 127.659 839.968 m -127.659 823.968 l +q 119.659 831.968 m +119.659 815.968 l 0.4 w S Q -q 143.659 839.968 m -143.659 823.968 l +q 135.659 831.968 m +135.659 815.968 l 0.4 w S Q -q 159.659 839.968 m -159.659 823.968 l +q 151.659 831.968 m +151.659 815.968 l 0.4 w S Q -q 8 792 m -8 776 l -264 776 l -264 792 l -h 0.8 w S -Q q 24 792 m 24 776 l 24 776 l @@ -529,10 +523,6 @@ q 232 792 m 232 776 l 0.4 w S Q -q 248 792 m -248 776 l -0.4 w S -Q q 1 0 0 1 10.6324 780 cm 1 0 0 1 0 0 cm 0 g 0 G 1 0 0 1 0 -784.296 cm @@ -610,7 +600,7 @@ BT 0 G ET Q -q 1 0 0 1 205.27 780 cm 1 0 0 1 0 0 cm 0.545 0 0 rg +q 1 0 0 1 221.448 780 cm 1 0 0 1 0 0 cm 0.545 0 0 rg 0.545 0 0 RG 1 0 0 1 0 -784.296 cm BT @@ -621,7 +611,7 @@ BT 0 G ET Q -q 1 0 0 1 221.016 780 cm 1 0 0 1 0 0 cm 0.545 0 0 rg +q 1 0 0 1 237.194 780 cm 1 0 0 1 0 0 cm 0.545 0 0 rg 0.545 0 0 RG 1 0 0 1 0 -784.296 cm BT @@ -632,39 +622,45 @@ BT 0 G ET Q +q 8 792 m +8 776 l +248 776 l +248 792 l +h 0.8 w S +Q showpage %%BeginIpeXml: /FlateDecode -%GhUDF9p;>1&A@sBW&X/cN0+YoVe2eUT_^qIn]/._&"Z7: -%]RDs][9t)NXX()*bG-n>ZiZ"DJOS^h%#Zrh[!meP^o"QESjj5fZ:rFj\TkK1q2%,]U[Sfnq@9pS -%-='$_k]kAd?=6LsoW?>qI4Rr&DWIQM$hJ%l[/#/,9B0bDbd-kX&n^`2q=abC:2e$Z:%BK$?XOeV -%j"e'a15b,caAsYL!!I8@6QEBLN@Aj`f6'ZDiOFp"UPB.R6\\13^as&BL6f;k<.'ddD=LJp34=@B -%$dC\)ekg]G;mZk;QcVA4k-=iKK-!p$@?N:mC_IR\g\IV@#3,3POkXja'\PZ985R(.nT\U7SO_dFf(o'+^AAP -%D"kK"6],uWV0P8oG4q<#hcB.pZ\$W8J>a&+eKnt'oI_9HC?D=?26G.benN/VhCe1E)lc)ai.]39 -%66Aps"L]sJ?me*5fZ3^6;H"P]1<`KD3YKi9h^CYTg]QA7Uq7N)'5CbUi<'`]H/7U/3rB"(E,`bq-9UdHiK?`CboMJ21%ErEX@+j"O]Z#3;1<3@k='.Ae:] -%p6m,(:s/=bFOW$sg?C^EVNoD+OEhbB=Z)bl`?>V,<]Z%:-K-:0p(D,Ub[=1u!2p"Qb;`8SZs4rL -%'`*Q5g"=Aj?kSaE/`!kNKt[ZDm]p]2.C4GW$U&(RK;Y4X/iML#n:5lACB]2$SWYKqh^a1Hp2--c\S_TBP]$So.;1Z`CQuiEcq]t> -%WgD^J&9dONfG&Gm5`%6_kPJ)ZW`jfmr92/q^=ra*(G",mAVS&elm>uZU^/hY-/gp0%-?aDBb.oV -%A2VjWA/q`&7GB`T0COatX/Vdle2_CGe:"-Ia%g'(bS)Pk_mQPf;ak!JG=-)FP=uKFb#.@kR'6/n -%,C$^tQlP-H@3C5o3iDF/rS0`R(VM?jF*VH7I;S#Yp>UQ#j0rAQS2rLb -%eiTEt*>q[\>,X);W-73G/e8E$AXXB+>%ilf#_G`_[+`d23bhK[s)WGUY\DGE.Y=e>ZhjPp3VopJ -%A?p_OphbaZ,d9#WTSt+]C:H^]N:l`5OZ[.C:I!G\M\b%.F0[Cgk5)Up+qR()r`rp$44D9;6&PRHR5%6G(_.l2";2a/lLfZ[Tg1[[s"IA4Q -%C@J2i(37ruVN)8M[o'jW"Uhi#W`m=qb&)41AhM*i2B*-j[2HfMaf=%)`cu#+FoJ-n#&1:DQWl!m -%neNg72;$VG08jlL1q34\8c@IKD=:R$-P#mV?JiYF]+,Pe[b,Ld:$)%%$0ObLg-Vbt"GLSUS$9u. -%pM+UQX6LPEF=aNU4^o1^o9]:gim8++7atp93;?g1;'>?A"e5?lKX9L\!9Y^\]AD"-LajPNAX5^G -%>0SYi<=SP6jS;eBYJ.(bF/A!@FK4doNOVpKJY8fW&paa$EI$p3nU0QbS5@NA.-IKlq2fG#6_"fU -%=[u]$hl8RqPAsN]Sh3(V,&<#>4^*CW307Yo[lEWNa!=h7l9A;p^:INEA`G)cLC*8ENbmTo.I*N$ -%_B#Kmeq4Lbm@D`YTZ!gJ;_%]RZ31-eAb0?9JY*919K)7`5?tXD;YF(Gi4LP5NqdkXU(M9jqE5A3 -%>8Q/I;Ejr9Q]Ji\_6B*-Xh[2[@W2#@;,mHV?g:h!eX\giY&9teQR;%6L+&t;+1R8 -%HPUPmorS.qAQlfdf*>#EW!P($%-kPIYcE#[mJ&H.nn'l3D7PO\eTV(iX-h\rFc;l\C"4#'k1PdOLM+"$He#sVWODQW=LgUhH^"TCPV -%`&hhEn%ptnYh=um_ead3ZRNZ4"%c;#*OlS"/=X3L4kt3VbFT&iL2?<2$d%@MB2X/<_CnkaU]1?s -%2-\]~> +%GhUDF9lK&M&A@sB&3B2"/;k2gd7"\@5`9N24n[P$+PX7TKU096S?,r%^V*#"_k]`?Z==iCK01>" +%h`M@'*(kKI[N*!O]L]@#d>:!P71PdL4>*u+!]/C2]6[SFsaak2ogMM^LO +%BY,rXB?;&1T$%gbir!@C:\)'ST*iqtauiFWAX78o&otU/FB!mkmTR/lLk-a/6rI%VbFsX@/[TC5 +%Uh5`'03?a\aRc]X]c?*[Q"R^G=+dlEJtQ-U*%S7O<\=,BJ/4`a,j0if&bOoncEcm\$E[%a=NXR/ +%c)rJJ/'NL_RCO@hf +%QR(=6VK#.icL\+c##8f,d.D%K^'[n?"YN-A77m07C8bSXTlJn0140P5c8sNj`s-IKp/Dmo3g%Pi +%(I(5,c&rd$00`hj4\s^ICMBV:,UnfGdu'/R[-fkFO6M"!1`"b^-L:F9o0miDIWFX"kJudKTpHj% +%02N%h[F@'p?PB"mkVX,;\;-kV-h7@K)4,1nG0*VM:;CJ<6Rk@_WC[#+Nq=O@=1e\?G#/2YJN1VJ +%-L"hMKG@*J][n1tX<>tt@)Wu>Hj,pN,0Tg;0]W +%le[F,<#^m?V'bGbnO-4s933qZ44&T"8!DqA->BI/i*.8'gu[F:=]4IW+G#DS,Y'WFp%"P^JsY2A +%WNU'9*!KpZ^OS[;-P)Fi.s/LdorMoXpVDn;-4KhoR$k#eN[_4YL;[uh'i3"T@oX/u&Re8WJ51IT +%op+'*GE="OX\1HdDHP/?b,_Kf +%(m4Pr>lLOKeM6:gZa/)3)#:jA\4=SaM?jJ2VoJ@ge&RdPHeH"e5?G<0gfG0`[28T/+2@cSiRFt5 +%\)-@klHY"X@\CI-TZk:C>hrS&b:G0mXOJ)V((%:+0ZqYH\nb/Hr9([EBD)-tebZJ% +%Ge/Dp\@,*i&i^_FUl6Oa]%N`jg\Q0k8=l[J:I!G\:DV[E;m\-7pA(Zs_B]84q@Cl5S'N[Nfq:=+ +%Z(Z`N2sV]m:MMR1#21G*C9NaChc4f>cNYa+4>O^j$HBFW+#.!;6(3%K,(nSfOe@O:1!r9%'%icZ +%fAKR79g(!V1f9qe"WOt3W_:8bau?kY3u9'CaX.t,ge?YNAC[8VKtMJg)ZT#[5oQ9/q,X@. +%H:o%8)T(2KQR@JNbjQQ0BtdfPj8DULLj778rB1qNFf^+4`-t(RX([r!4>2n""/Xic'WM8#;T(9R81XF=_,]=Y_l4n +%[3+SL*j#a621Y5qXkQkt>2s,2&ZLU3EYZ<+!W=(0%lbXh%LN.*Q=d^fc1D.Z6XCp1Yl2DZS[,=ZIb)uIA8LN$SH +%Ba:6m,/sg%4cH)YKpPb%EoKJ7eH[7cSuk3Km[tWM;sMob2g2Y+.5BA^*uOHlR_Dn;4>5MVIW2(3 +%M8FV8:2i8hTaqBfZ\)';4b?IJ'RWUCZ>f=?q3\`ZJBq#>ieR8a^40 %%EndIpeXml %%Trailer end From ec5f75861d967363240bf1d9748f4c2e809ed118 Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Sun, 15 Nov 2015 12:22:36 -0500 Subject: [PATCH 04/14] Remove blank line. --- .../segment-tree/problems/coming-and-going/coming-and-going.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp b/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp index 311f825..156aca7 100644 --- a/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp +++ b/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp @@ -64,7 +64,6 @@ void update_segment_tree(int* const tree, const unsigned int start, const unsign // #ifdef hackpackpp // update a value in the segment tree // - // To support range sums, this function would have to be modified to recurse // down the tree to the leaf node before changing values. After the leaf node // is updated, the new value should be passed back as a return value and each From d6c2e57e0469f8e88ed8d21a1bea3af2927b7a0e Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Sun, 15 Nov 2015 17:04:36 -0500 Subject: [PATCH 05/14] Fix typo. --- structures/segment-tree/segment-tree.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/structures/segment-tree/segment-tree.tex b/structures/segment-tree/segment-tree.tex index bad9fb4..010b3a5 100644 --- a/structures/segment-tree/segment-tree.tex +++ b/structures/segment-tree/segment-tree.tex @@ -33,7 +33,7 @@ \section{Segment Tree} A segment tree is represented as an array of a size that is dependent on the dataset it is sourced from. For a given array of size $n$, a segment tree constructed from it will use up to $2^{\lceil \log_2 (n)\rceil + 1} - 1$ space. -To properly represent tree, the root is located at index 0; its left and right children are located at indices 1 and 2 respectively. +To properly represent the tree, the root is located at index 0; its left and right children are located at indices 1 and 2 respectively. To properly recurse through the tree, indices of left and right children can be calculated with $2n + 1$ and $2n + 2$ for left and right children respectively. Construction of a segment tree begins at the root. From 3ee7f0753ccd80b0d05dfaa23dfb351698812e59 Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Sun, 15 Nov 2015 17:13:27 -0500 Subject: [PATCH 06/14] Add extra information. --- structures/segment-tree/segment-tree.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/structures/segment-tree/segment-tree.tex b/structures/segment-tree/segment-tree.tex index 010b3a5..36e77a9 100644 --- a/structures/segment-tree/segment-tree.tex +++ b/structures/segment-tree/segment-tree.tex @@ -9,6 +9,7 @@ \section{Segment Tree} The prefix sum calculation only takes $O(n)$ time to perform, and any query thereafter takes only $O(1)$ time. But any updates to the source dataset will require $O(n)$ time to update the prefix sum calculations. Frequent changes will quickly show the pitfall of this approach. +This precalculation approach will also not work for finding minimum or maximum values in an arbitrary range. A segment tree is a data structure for storing information about intervals that can be constructed in $O(n)$ time. Whenever the source data changes, update times stay low at $O(\log n)$ time. From cf0b9921e6fd2daddb5a0e2631ed3259639bb54b Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Mon, 16 Nov 2015 07:08:43 -0500 Subject: [PATCH 07/14] Remove irrelevant informatin. The hint on changing the function to support range sums is no longer important since this is easily done by the segment tree provided in the reference code. --- .../problems/coming-and-going/coming-and-going.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp b/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp index 156aca7..bf39bda 100644 --- a/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp +++ b/structures/segment-tree/problems/coming-and-going/coming-and-going.cpp @@ -64,16 +64,6 @@ void update_segment_tree(int* const tree, const unsigned int start, const unsign // #ifdef hackpackpp // update a value in the segment tree // - // To support range sums, this function would have to be modified to recurse - // down the tree to the leaf node before changing values. After the leaf node - // is updated, the new value should be passed back as a return value and each - // parent should update the sum they have by re-adding the values from the - // two children it has. - // - // Alternatively, the old value (or at least some delta) could be an additional - // argument passed in during the original call. Nodes could update to their new - // respective values without waiting for children to report sums back. - // // tree - the segment tree with values to be updated // start - the start index of the _source_ array (should be 0) // end - the end index of the _source_ array (size - 1) From 2f4a70cd28819c934215b0c953e63a46f529c5f4 Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Mon, 16 Nov 2015 07:51:52 -0500 Subject: [PATCH 08/14] Change to class-based segment tree. The class version is a bit more heavy-weight than the set of functions, but this should support multiple segment trees of varying types at once. --- structures/segment-tree/segment-tree.cpp | 206 ++++++++++++++--------- 1 file changed, 123 insertions(+), 83 deletions(-) diff --git a/structures/segment-tree/segment-tree.cpp b/structures/segment-tree/segment-tree.cpp index 3f3ac7a..fbb21b4 100644 --- a/structures/segment-tree/segment-tree.cpp +++ b/structures/segment-tree/segment-tree.cpp @@ -9,75 +9,122 @@ using namespace std; // choose information to store enum SegmentTreeType { ST_MIN, ST_MAX, ST_SUM }; -const SegmentTreeType type = ST_MIN; -// number of entries in array -unsigned int N = 10; - -int segment_tree_helper(const int a, const int b) +class SegmentTree { - if(type == ST_MIN) - return (a < b ? a : b); - else if(type == ST_MAX) - return (a > b ? a : b); - else if(type == ST_SUM) - return (a + b); - else - return -1; -} +public: + SegmentTree() : type(ST_MIN), size(0), tree(NULL) {} -int build_segment_tree(int* const data, const unsigned int start, const unsigned int end, int* const tree, const unsigned int st_idx) -{ - if(start == end) + SegmentTree(SegmentTreeType type, const unsigned int size) : type(type), size(size) { - tree[st_idx] = data[start]; - return data[start]; + tree = new int[size]; } - const unsigned int mid = start + ((end - start) / 2); - const int left = build_segment_tree(data, start, mid, tree, (2 * st_idx) + 1); - const int right = build_segment_tree(data, mid + 1, end, tree, (2 * st_idx) + 2); + ~SegmentTree() + { + delete[] tree; + } - tree[st_idx] = segment_tree_helper(left, right); + int build(int* const data, const unsigned int start, const unsigned int end, const unsigned int st_idx) + { + if(start == end) + { + tree[st_idx] = data[start]; + return data[start]; + } - return tree[st_idx]; -} + const unsigned int mid = start + ((end - start) / 2); + const int left = build(data, start, mid, (2 * st_idx) + 1); + const int right = build(data, mid + 1, end, (2 * st_idx) + 2); -void update_segment_tree(int* const tree, const unsigned int start, const unsigned int end, const unsigned int changed_idx, const int old_val, const int new_val, const unsigned int st_idx) -{ - if(changed_idx < start || changed_idx > end) - return; + tree[st_idx] = helper(left, right); - if(type == ST_MIN) - { - if(new_val < tree[st_idx] || start == end) - tree[st_idx] = new_val; + return tree[st_idx]; } - else if(type == ST_MAX) + + void update(const unsigned int start, const unsigned int end, const unsigned int changed_idx, const int old_val, const int new_val, const unsigned int st_idx) { - if(new_val > tree[st_idx] || start == end) - tree[st_idx] = new_val; + if(changed_idx < start || changed_idx > end) + return; + + if(type == ST_MIN) + { + if(new_val < tree[st_idx] || start == end) + tree[st_idx] = new_val; + } + else if(type == ST_MAX) + { + if(new_val > tree[st_idx] || start == end) + tree[st_idx] = new_val; + } + else if(type == ST_SUM) + { + int delta = new_val - old_val; + tree[st_idx] += delta; + } + + + if(start == end) + return; + + const unsigned int mid = start + ((end - start) / 2); + update(start, mid, changed_idx, old_val, new_val, (2 * st_idx) + 1); + update(mid + 1, end, changed_idx, old_val, new_val, (2 * st_idx) + 2); + + return; } - else if(type == ST_SUM) + + int query(const unsigned int start, const unsigned int end, const unsigned int range_start, const unsigned int range_end, int val, const unsigned int st_idx) { - int delta = new_val - old_val; - tree[st_idx] += delta; + if(start > range_end || end < range_start) + { + if(type == ST_MIN) + return ST_QUERY_DUMMY_MAX; + else if(type == ST_MAX) + return ST_QUERY_DUMMY_MIN; + else if(type == ST_SUM) + return ST_QUERY_DUMMY_SUM; + } + + if(start == end) + return tree[st_idx]; + + if(type == ST_MIN && (start >= range_start && end <= range_end)) + { + if(tree[st_idx] < val) + return tree[st_idx]; + } + else if(type == ST_MAX && (start >= range_start && end <= range_end)) + { + if(tree[st_idx] > val) + return tree[st_idx]; + } + else if(type == ST_SUM && (start >= range_start && end <= range_end)) + { + return tree[st_idx]; + } + else + { + const unsigned int mid = start + ((end - start) / 2); + const int left = query(start, mid, range_start, range_end, val, (2 * st_idx) + 1); + const int right = query(mid + 1, end, range_start, range_end, val, (2 * st_idx) + 2); + val = helper(left, right); + } + + return val; } - - if(start == end) - return; - - const unsigned int mid = start + ((end - start) / 2); - update_segment_tree(tree, start, mid, changed_idx, old_val, new_val, (2 * st_idx) + 1); - update_segment_tree(tree, mid + 1, end, changed_idx, old_val, new_val, (2 * st_idx) + 2); + SegmentTreeType get_type() + { + return type; + } - return; -} + unsigned int get_size() + { + return size; + } -int query_segment_tree(const int* const tree, const unsigned int start, const unsigned int end, const unsigned int range_start, const unsigned int range_end, int val, const unsigned int st_idx) -{ - if(start > range_end || end < range_start) + int get_dummy_val() { if(type == ST_MIN) return ST_QUERY_DUMMY_MAX; @@ -85,35 +132,30 @@ int query_segment_tree(const int* const tree, const unsigned int start, const un return ST_QUERY_DUMMY_MIN; else if(type == ST_SUM) return ST_QUERY_DUMMY_SUM; + else + return -1; } - if(start == end) - return tree[st_idx]; +protected: + SegmentTreeType type; + unsigned int size; + int* tree; - if(type == ST_MIN && (start >= range_start && end <= range_end)) - { - if(tree[st_idx] < val) - return tree[st_idx]; - } - else if(type == ST_MAX && (start >= range_start && end <= range_end)) + int helper(const int a, const int b) { - if(tree[st_idx] > val) - return tree[st_idx]; - } - else if(type == ST_SUM && (start >= range_start && end <= range_end)) - { - return tree[st_idx]; - } - else - { - const unsigned int mid = start + ((end - start) / 2); - const int left = query_segment_tree(tree, start, mid, range_start, range_end, val, (2 * st_idx) + 1); - const int right = query_segment_tree(tree, mid + 1, end, range_start, range_end, val, (2 * st_idx) + 2); - val = segment_tree_helper(left, right); + if(type == ST_MIN) + return (a < b ? a : b); + else if(type == ST_MAX) + return (a > b ? a : b); + else if(type == ST_SUM) + return (a + b); + else + return -1; } +}; - return val; -} +// number of entries in array +unsigned int N = 10; int main() { @@ -122,29 +164,27 @@ int main() // size needed for segtree is 2^{ceil(log2(n)) + 1} - 1 const unsigned int st_size = pow(2, ceil(log2(N)) + 1) - 1; - int* segtree = new int[st_size]; - build_segment_tree(src_array, 0, N - 1, segtree, 0); + SegmentTree segtree(ST_MAX, st_size); + segtree.build(src_array, 0, N - 1, 0); // update value in segtree int old = src_array[4]; src_array[4] = 43; - update_segment_tree(segtree, 0, N - 1, 4, old, 43, 0); + segtree.update(0, N - 1, 4, old, 43, 0); old = src_array[2]; src_array[2] = 21; - update_segment_tree(segtree, 0, N - 1, 2, old, 21, 0); + segtree.update(0, N - 1, 2, old, 21, 0); old = src_array[3]; src_array[3] = 2; - update_segment_tree(segtree, 0, N - 1, 3, old, 2, 0); + segtree.update(0, N - 1, 3, old, 2, 0); old = src_array[9]; src_array[9] = 1; - update_segment_tree(segtree, 0, N - 1, 9, old, 1, 0); + segtree.update(0, N - 1, 9, old, 1, 0); // query segtree between indices 0 and 9, inclusive - int result = query_segment_tree(segtree, 0, N - 1, 0, 9, ST_QUERY_DUMMY_MAX, 0); + int result = segtree.query(0, N - 1, 0, 9, segtree.get_dummy_val(), 0); cout << result << endl; - delete[] segtree; - return 0; } From 1343bfc90b91f58655c17e0067a185579e0ff886 Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Mon, 16 Nov 2015 07:54:38 -0500 Subject: [PATCH 09/14] Show that the data represents single cows. --- structures/segment-tree/segment-tree.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/structures/segment-tree/segment-tree.tex b/structures/segment-tree/segment-tree.tex index 36e77a9..fb1110f 100644 --- a/structures/segment-tree/segment-tree.tex +++ b/structures/segment-tree/segment-tree.tex @@ -103,7 +103,7 @@ \subsubsection{Input Format} \begin{itemize} \item Line 2: A single integer, $C$, representing the number of cows Farmer John has data on. - \item The following lines are placed in $C$ groups detailed as follows: + \item The following lines are placed in $C$ groups, each describing the movements of a single cow, detailed as follows: \begin{itemize} \item A single line containing a single integer, $k$, representing the number of time ranges to follow that the cow was present in the barn. From a8c8db05db556f7574141b3d3f6e5779b2abd06f Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Mon, 16 Nov 2015 12:20:10 -0500 Subject: [PATCH 10/14] Remove empty leaves. --- structures/segment-tree/array-tree.eps | 117 ++++++++----------------- 1 file changed, 37 insertions(+), 80 deletions(-) diff --git a/structures/segment-tree/array-tree.eps b/structures/segment-tree/array-tree.eps index a0655cb..26cb17d 100644 --- a/structures/segment-tree/array-tree.eps +++ b/structures/segment-tree/array-tree.eps @@ -1,6 +1,6 @@ %!PS-Adobe-3.0 EPSF-3.0 %%Creator: Ipelib 70108 (Ipe 7.1.8) -%%CreationDate: D:20151112191236 +%%CreationDate: D:20151116121728 %%LanguageLevel: 2 %%BoundingBox: 7 687 265 836 %%HiResBoundingBox: 7.65294 687.768 264.453 835.317 @@ -386,36 +386,18 @@ q f* Q 0.4 w 0 g S Q q 172 780 m -188 756 l -0.678 0.847 0.902 rg -q f* Q 0.4 w 0 g -S -Q -q 172 780 m 156 756 l 0.678 0.847 0.902 rg q f* Q 0.4 w 0 g S Q q 100 780 m -116 756 l -0.678 0.847 0.902 rg -q f* Q 0.4 w 0 g -S -Q -q 100 780 m 84 756 l 0.678 0.847 0.902 rg q f* Q 0.4 w 0 g S Q q 36 780 m -52 756 l -0.678 0.847 0.902 rg -q f* Q 0.4 w 0 g -S -Q -q 36 780 m 20 756 l 0.678 0.847 0.902 rg q f* Q 0.4 w 0 g @@ -583,14 +565,6 @@ h 0.678 0.847 0.902 rg q f* Q 0.8 w 0 g S Q -q 40.0529 746.917 m -40.0529 762.917 l -64.0529 762.917 l -64.0529 746.917 l -h 0.678 0.847 0.902 rg -q f* Q 0.8 w 0 g -S -Q q 72.0529 762.917 m 72.0529 746.917 l 96.0529 746.917 l @@ -599,14 +573,6 @@ h 0.678 0.847 0.902 rg q f* Q 0.8 w 0 g S Q -q 104.053 746.917 m -104.053 762.917 l -128.053 762.917 l -128.053 746.917 l -h 0.678 0.847 0.902 rg -q f* Q 0.8 w 0 g -S -Q q 144.053 762.917 m 144.053 746.917 l 168.053 746.917 l @@ -615,14 +581,6 @@ h 0.678 0.847 0.902 rg q f* Q 0.8 w 0 g S Q -q 176.053 746.917 m -176.053 762.917 l -200.053 762.917 l -200.053 746.917 l -h 0.678 0.847 0.902 rg -q f* Q 0.8 w 0 g -S -Q q 208.053 762.917 m 208.053 746.917 l 232.053 746.917 l @@ -793,43 +751,42 @@ q 168 708 m Q showpage %%BeginIpeXml: /FlateDecode -%GhU\O6$'(d'#+6EW-io40Th#"@d>=?>I@Zk;`1JdDWX3#CfA0i"#tRoWS-1Ch%F+(jCcOASi8Zs -%7f(X5WR[/8,+m=O6=,hL9_85]4J[pjF0[?[\B9a,q9MkTHH]=ZLY:j4^WoPRZFZ\.lQ;Y&JAEVS'$$[Qe-(X9gn#< -%:$!&R.4BP@F%4OqlCR`)g;V&&h(gRJ=n8Np5,9[fIC[X]?!K[3QhPQ,OIR">;)q4+=[PpX(4S1Y,U_s:mKA`8NS$XdsNYue-nlEjLQSsN2f#+E`b;Zu_ -%`H$P%oZqF+MO>WkV8Z$]ienrUB/aVFb]HNOMj$+SI*:E-EUg0i40BC;_Pn^P&HT;T8CB`7=Y")2 -%cEsrH^]IX9tk67d:_^^'$XO&pZ,e?BBonb:T^'i&WY.mr0Wp7r6nme8WRYI1d@J)4cn'c0mK]Y3ges=QRRNgrCe$(TbDuI]DSk -%I5HuJqifQSYQ_]teSPr6Ue*9g06)/gG6ePHOe33N\8#fIa3SL])(\fH_uPam1B"mXl*InP,V:E` -%K1]5OZ>5o/FT5qb@N)(+IaK.1:/KPIi5B`=q&6Q_Zb36;Me$t9K#pUqYpg;&`7DVT3A=6*B0cOI -%K=iL5QG6V3>^CGC2sbGB7OCGYMJmKF1;GQHH/[hFS@=JT42DA&*(LZ',"a[`LCCF`KjP! -%i@?/ni>II8JpMcU[AnSp/DY-CY1l'Q`^IjIj9QLVVX$H0Nm'6F2"o.=MMIO;h5C[&:tOaq#]8D= -%26i:(7^(flCL<%Y]B,CZMI1.koRM3efg&%)MbnXGkBK9P&E26p>\[o\Xcb?f`Kg8H]K1#HFE,'# -%`;T9l5Q9ESkuS+-HaM>f2[AWG%dKr"W:%[qBO2^hFe2\3]Ws@P,m\P!k\N2=qQ31hra3Od_bL"W -%fqa]Z4R2)OVY&1p8bOY_K\s5ZV$%F+*RZpr;AXQ,Zt5Tr>Z1-K_B5+eD2NFHF^L4t;+Q?@%Z%Y`]Ik+4&saa#+eh3jjXIs%6X!-\J*1T%6i8-F9ca^!K9(> -%SK8(UO74b_0J7q<3D1oJ7*-q3[&AdA;6l+CDA4Y[2QGUXc;B$lQg`ME\_#Ad"XZ-+314U:bVd;I -%3RR6_k6mpe)0g2;cm#[XWnN&/qsB9J[%$k->MV12eiLM%i$40;P%K-'Zbn]P5Y/.eM68=t@M1>p -%oVI2g-NoED6+aWVdP#`\M-C(5Qlu^)C"mo[RX!!7j`>L)3,OK_1TI- -%,kUU^Ku3=*f+:'+.43Y5Ksk@%na(]S:jGiOGV;kjdd0oAT5X\:q-(S'X_.Uiso2@:Voj) -%'$8i\;<&.Vd["uRcepW8Y0iE@bp9]nRsKi]Hh(BijUB2B+B6'N)"jV2>R)CQ6_u-lc`S7E(l'.t -%JcQ*:3+D[CH2pIH)t`(2@8n[8oJ8Tu$]bOT(`>d%-DSAjhM2:/U/:WH\,2h_L!dD*kkj+cSbR`! -%T">@=`ds"4GC`5(A16\XgSqf(jd<^ePii9&_UF\b73gEZkQYO9AMIAA![]^iAdfA[L&K8B!5*^\ -%Hcj3l?9jbm]qYMV=(?49%]Ks^,amh214QV?7,3t_@O?a0'o^u]rp!.j0_Bqsg;q1\<]+.XA>6sI4MNabO^#uoW_B'2]HkYK[IU#>E,[%oMNB:M1CnS;1r:_L:#!>"K"XOS3qlDq`CGmu9!ig!t%CJ$d2`\.>qG"4ZFcGl~> +%GhU\O;3Rb5&q9SY;#+hs?q(bqLo[)G\uNA7;O+/,]u^@dA"+BQ*5F?l8`bEuF\@7=Ok29K31G=M +%NV'4IlW,7<2#B9r,ig7#aucU5ig3%)lnM6";!TDo=jTuT8QJ!bXZpZpUV-*-q=^])%u$Q/eo +%Vke-(G53UnVk$#n3"*9chr4&l;H@^=6MBq%\Xu+*A\(:;jkK2Pcg')k..Z!%\6+20%pse$mR(5r +%8Qcf(1NW_B@H9FOVchSf3@&t#!!3S*KTb/-_$K^]h^9;!MalRK52W&KY]+4l\>cQ"E-^9:eO25( +%ePn8sSq=Cp#%nXPU#C8=UKq+eh_!;dR3eIti'XLghO!Q@fYnTdG'Q=(%@MKWl1Q;*N''[n\$?bRtr +%/sZm@Vgilr=UZW>:D +%SnVnY'"@=$[bFL9OFa +%(5@.-fV@K[pTT_@koS!6mr0Wp7r6nme8WRYI1d@J)4cn'c0mK]Y3gef=QRRNgrCed([SqdId6+V +%@l050qhs!KYQ_]teSPr6Ue*9g06)/gG=W'HOe33N\8$AYa3T'm)(\fH_uPam1B"m8l*InP,V:E` +%K1]5OZ>5o/FT5qb@N)'fIaK.1:/KPIi5B`=q&6Q_Zb36KMe$t9K#L=mYpg8]3A=7UB0cOI +%K=iL5QG6V3>^CGC2f,sC,86c/<1\5WHO:Sc*pdhs%[k;[P8kBb`c2NL"EQOA^KL&&"FXW#^3a(\ +%cmiU7IXCj2X1F)1d`o5cL@?/.(L +%EW>s_O8lY-qUL/O*c6&rc%5_jKDOg6Wk375RTB`3S`eNeY:PZ-$\DV.3nqoSIVVe]r0Qp7iMQR< +%Cf2Yr*qf+8e,&6t,l8<5_Je2i;?DR"%V_GIWLGtag9sY#/h)'6iK)0n2FY3_g_]$JQ*()'"]5OK +%TDf'QjR.d=Wa&@ICTQl1lc&]/m.2.>GR*VWVeXr4^pC&CS@[XkJVP7"GCl6]_.T4-iS[EmJ5JhE +%1Eo*u&`,q]-7#fXB8HeQ-s7jc()9[o8p4([NIh>h7b(_]3QggUo%gl:pU](__;o28-^.8/\RtUp +%-[P^hHi_`i!`';n>3%PH*nt&Ht;bOd]DnWG1aeQ#UT0pd9U>49]BWK +%^3!3JKV20oBGX`=qPC>HEGH\Y1ZX'ng32>E-D%Mfq:lr8:0Z_q9I^Z)4<-%I8LUQdb0nkT;*PRN +%$%9H[iUAp_JQaWBJ!XXRV+:H3J\>&&lMaha.Th,Na)"7!ph@@,AHV1Se&I^c:piE`8OR)_P7nJ0&m(1uhCS5^@`*GG +%EdHSO+E*91iIUNRKAkn(rN!RUV8A@O_VepmS@NC&44f!*J/%H+muhs`#tS]hIs=3Z(hYXTg(G3^ +%>Q"#7@*^NM!a0=-$f>\$Fspi&Kb)S0<36ad&(/I+oen;-1dEE:$@(W%5*:q^/7_*`F`WnB06ite +%=7?DP-=#Kf#mFq*&6:Mh5pY5T5>K:!B58 +%.C9rt%q+.DirKjsr\tGHTPsuDXrMGGJtjU/Z^L<-&;cNP,]5@Fm-?hd\/0k9LMG0@V(@SF3MA+> +%#!28Tk6JI(%-E+u5eB9+3AQll?.[RY>WKGK!p04YMm+Q&U1iV6']!.,Xt3&#:r(,qV3qF>(G(%l +%%tM,B?r'r#dL2udUK>s[qSECGF!:3"Kd?8;:$-BV5f>fW,A'h%:r2?9iNKsV$:?HP?o>b %%EndIpeXml %%Trailer end From 77e8f2fc7aa2fec9c2bdadeb34adc7fbc08e3844 Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Tue, 17 Nov 2015 21:18:57 -0500 Subject: [PATCH 11/14] Add section headers for sample I/O. --- structures/segment-tree/segment-tree.tex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/structures/segment-tree/segment-tree.tex b/structures/segment-tree/segment-tree.tex index fb1110f..f55be2a 100644 --- a/structures/segment-tree/segment-tree.tex +++ b/structures/segment-tree/segment-tree.tex @@ -114,6 +114,8 @@ \subsubsection{Input Format} \end{itemize} \end{itemize} +\subsubsection{Sample Input} + \acmlisting[label=Coming and Going Sample Input, caption=Coming and Going Sample Input]{./structures/segment-tree/problems/coming-and-going/coming-and-going.in} \subsubsection{Output Format} @@ -121,6 +123,8 @@ \subsubsection{Output Format} $C$ lines indicating the maximum number of cows seen in the barn in a single hour after adding data for the 1\textsuperscript{st}, 2\textsuperscript{nd}, \ldots, $C$\textsuperscript{th} cow. Each should appear on its own separate line formatted as given in the sample output. +\subsubsection{Sample Output} + \acmlisting[label=Coming and Going Sample Output, caption=Coming and Going Sample Output]{./structures/segment-tree/problems/coming-and-going/coming-and-going.out} \subsubsection{Sample Solution} From d2744aea538caad5d24b1b4594abf3ef65d4a7fa Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Tue, 17 Nov 2015 21:41:57 -0500 Subject: [PATCH 12/14] Add another sample problem. --- hackpack.bib | 7 ++++ .../optimal-milking/optimal-milking.in | 10 +++++ .../optimal-milking/optimal-milking.out | 2 + structures/segment-tree/segment-tree.tex | 40 +++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 structures/segment-tree/problems/optimal-milking/optimal-milking.in create mode 100644 structures/segment-tree/problems/optimal-milking/optimal-milking.out diff --git a/hackpack.bib b/hackpack.bib index 6358c99..fca1c3d 100644 --- a/hackpack.bib +++ b/hackpack.bib @@ -40,6 +40,13 @@ @misc{dppractice url = "http://people.cs.clemson.edu/~bcdean/dp_practice/" } +@misc{optimalmilking, + author = "Dr. Brian Dean", + title = "Optimal Milking", + year = "2013", + url = "http://usaco.org/index.php?page=viewproblem2&cpid=365" +} + @misc{acmsoutheastregional2013, author = "ACM Southeast Regional", title = "ACM Southeast Regional 2013", diff --git a/structures/segment-tree/problems/optimal-milking/optimal-milking.in b/structures/segment-tree/problems/optimal-milking/optimal-milking.in new file mode 100644 index 0000000..6f88473 --- /dev/null +++ b/structures/segment-tree/problems/optimal-milking/optimal-milking.in @@ -0,0 +1,10 @@ +5 3 +1 +2 +3 +4 +5 +5 2 +2 7 +1 10 + diff --git a/structures/segment-tree/problems/optimal-milking/optimal-milking.out b/structures/segment-tree/problems/optimal-milking/optimal-milking.out new file mode 100644 index 0000000..87a9288 --- /dev/null +++ b/structures/segment-tree/problems/optimal-milking/optimal-milking.out @@ -0,0 +1,2 @@ +32 + diff --git a/structures/segment-tree/segment-tree.tex b/structures/segment-tree/segment-tree.tex index f55be2a..e85310a 100644 --- a/structures/segment-tree/segment-tree.tex +++ b/structures/segment-tree/segment-tree.tex @@ -142,3 +142,43 @@ \subsubsection{Lessons Learned} \end{itemize} % #endif + +% #ifdef hackpackpp + +\subsection{USACO Contest Problem: Optimal Milking\cite{optimalmilking}} + +Farmer John has recently purchased a new barn containing $N$ milking machines ($1 \leq N \leq 40,000$), conveniently numbered $1$..$N$ and arranged in a row. + +Milking machine $i$ is capable of extracting $M(i)$ units of milk per day ($1 \leq +M(i) \leq 100,000$). +Unfortunately, the machines were installed so close together that if a machine $i$ is in use on a particular day, its two neighboring machines cannot be used that day (endpoint machines have only one neighbor, of course). +Farmer John is free to select different subsets of machines to operate on different days. + +Farmer John is interested in computing the maximum amount of milk he can +extract over a series of $D$ days ($1 \leq D \leq 50,000$). +At the beginning of each day, he has enough time to perform maintenance on one selected milking machine $i$, thereby changing its daily milk output $M(i)$ from that day forward. +Given a list of these daily modifications, please tell Farmer John how much milk he can produce over $D$ days (note that this number might not fit into a 32-bit integer). + +\subsubsection{Input Format} + +\begin{itemize} + \item Line 1: The values of $N$ and $D$. + \item Line 2..$1+N$: Line $i+1$ contains the initial value of $M(i)$. + \item Lines $2+N$..$1+N+d$: Line $1+N+d$ contains two integers, $i$ and $m$, indicating that Farmer John updates the value of $M(i)$ to $m$ at the beginning of day $d$. +\end{itemize} + +\subsubsection{Sample Input} + +\acmlisting[label=Optimal Milking Sample Input, caption=Optimal Milking Sample Output]{./structures/segment-tree/problems/optimal-milking/optimal-milking.in} + +\subsubsection{Output Format} + +\begin{itemize} + \item Line 1: The maximum total amount of milk FJ can produce over $D$ days. +\end{itemize} + +\subsubsection{Sample Output} + +\acmlisting[label=Optimal Milking Sample Input, caption=Optimal Milking Sample Output]{./structures/segment-tree/problems/optimal-milking/optimal-milking.in} + +% #endif From a2c57ae45959a5cfd87c208c6514f24d2de9fef5 Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Tue, 17 Nov 2015 21:42:33 -0500 Subject: [PATCH 13/14] Fix line number. --- structures/segment-tree/segment-tree.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/structures/segment-tree/segment-tree.tex b/structures/segment-tree/segment-tree.tex index e85310a..d94faab 100644 --- a/structures/segment-tree/segment-tree.tex +++ b/structures/segment-tree/segment-tree.tex @@ -101,7 +101,7 @@ \subsection{Example Contest Problem: Coming and Going} \subsubsection{Input Format} \begin{itemize} - \item Line 2: A single integer, $C$, representing the number of cows Farmer John has data on. + \item Line 1: A single integer, $C$, representing the number of cows Farmer John has data on. \item The following lines are placed in $C$ groups, each describing the movements of a single cow, detailed as follows: \begin{itemize} From 3200969a26cbdf47b88313c9799694deab663082 Mon Sep 17 00:00:00 2001 From: Marshall Clyburn Date: Sat, 21 Nov 2015 21:02:44 -0500 Subject: [PATCH 14/14] Include reference code in hackpackpp. --- structures/segment-tree/segment-tree.tex | 5 ----- 1 file changed, 5 deletions(-) diff --git a/structures/segment-tree/segment-tree.tex b/structures/segment-tree/segment-tree.tex index d94faab..49dea9a 100644 --- a/structures/segment-tree/segment-tree.tex +++ b/structures/segment-tree/segment-tree.tex @@ -61,13 +61,8 @@ \section{Segment Tree} % #endif -% #ifdef hackpack - \acmlisting[label=Segment Tree Reference Code, caption=Segment Tree Reference Code]{./structures/segment-tree/segment-tree.cpp} -% #endif - - % #ifdef hackpackpp Generally, a segment tree supports two operations: update and query.