 What's up guys, Mike the coder here today. We're going to go over the spodge question of can you answer these queries? So this is a problem that requires the understanding of segment trees or finwick tree, whichever you want to use But basically you're given a sequence of array of numbers And then now you're going to get a query So the query is basically two indices X and Y and you want to find the maximum sum from Between the two indices Right, so the maximum sum this is like a maximum of AI plus AI plus one up to AJ And that's basically the values between these two indices. So the maximum sum between these two indices that when you add up the values between So now you're given the M queries and your program has to output the results of these queries Okay, so what you could do is you could try using prefix sum and suffix sum But then you have to literally compute every single time and that's Actually not a good way to do it. So the best way is actually to use a segment tree. So Yeah, okay, so basically, I kind of just blackbox this but How you how you how you want to do this is that? So you have the values of of the left side and the right side So you have a let's say I have the very negative one two and three, right? So I if I go from left to right and I sum up the values from prefix sum would have Let's see. I have negative one But negative one plus two would be one one plus three is four, right? This is from left to right and then if I sum up from right to left Right. So this is left to right. So this is gonna be my prefix. Um, now if they're if I sum up from right to left It would be three plus two is five Right three plus two is five and then five plus negative one is four, right? So then basically what we have to do is we have to like find The values between like the prefix sum and the suffix sum such that the value would be the largest So in this case, it would be probably five because we have to add two and three, right? That's the five which is the largest out of all these so in order to do this basically you have to have a segment tree that has Three instance variables actually for four four instance variables. Okay. One is gonna store the the sum Of your current like segment. The other one's gonna sort of like the left sum which is like coming from the left side And the other one's gonna sort of the right some it's coming from the right side To some of the values and then you're gonna get the actual Final instance variables because they be max sum which is gonna give us the It's just gonna do like their comparison between left and right and find the maximum actual sum. Okay, so that's what we're gonna have okay, um I think I'm just gonna show you guys a code and try to explain it because it's kind of a little confusing how we're gonna do this, but Yeah, I kind of black boxed it So I don't I don't not a hundred percent like confident about segmentaries, but I could explain it to you pretty decently Okay. All right, so let's start with the main method because main is really easy Okay, so I have an array of a and here I just read in number values n and I'm gonna read in the array of a right So this is gonna loop through the values of n and it's gonna read in the array of a okay Then I'm gonna call a method called build and it's gonna build my segment tree and in the segment tree I'm going to basically store these values right the left sum Right some and the maximum some between both of these guys cuz like you need the sum between both the segments from left Side and the right side and you need to find the maximum sum for that So the method is gonna be build. Okay, and then I'm passing in zero and n minus one because that's gonna be the Starting point. So you're gonna start from zero Here this is index zero and then any point is gonna be n minus one Right because that's the zero one two Right, those are the indices zero one two and then n minus one is the last index, right? Give the number of values All right, so that's gonna build up the segment tree and the bill once I have the segment tree That's going to store all these values of the prefix sum and suffix them for each of them and then Then every time we Read in M and then we're gonna read an X and Y that's gonna read in the queries the index indices that we do right, so then what I do is I subtract X minus one and Y minus one because I want in Because the problem is indexing by one and I want to index it from zero So that's why I subtract both of the indices by one and I'm gonna call query and query. I'm gonna pass in the Starting value and then the starting right from the start to the end and my zero to n minus one and I'm passing the two Indices that I want to find the maximum of and it's just gonna call that Okay, so now let's actually get down to the build method because building the segment tree is the hard part And then when you just query it you could just Query it that's the easier part. So let's actually go to the build method Okay, so actually before we before we get down to the build method out Let's go back to the top part. So first of all here. I Have a structure Which are you could use a class in Java and C++ structures are basically just like classes Except like all the values are private. I think if I recall, but anyway, I have a structure And it's gonna have a store the sum of some Maximum the sum from the left and the sum from the right and that's basically what I said early on the sum left right and the maximum Okay, that's what this structure. So has okay. So now I'm gonna have this segment tree and that's just going to be um, I Just do n Shift left by four because I think you need to have at least like four Every four leaf you need to have like four four nodes So that's what you need to have and here a I do n shift left by four. So this big n is Big n is the number of values we have. So that's the maximum of our values We have that's the constraints from the input statement and they said 50,000 is the maximum possible number of elements you could have so that's why I do that here and Yeah, this part is just to take care of leaves. Okay All right, get middle is just going to return like the difference in between the middle between the values of a and b So it's gonna get the center value and we use get middle in order to like get the It's useful if you want to get the middle value in your array Given the two values a and b. So that's what we're gonna use that sooner later. Okay. All right empty node is just going to set all the left Sum right some total sum and the max sum to be zero. So that's what the empty node is It's just a node that has all the values to be zero and it returns it. Okay Now let's go back to the build method. So what do we do in the build method? All right, so if if my sum from that I'm summing from and To right where I'm summing from and where I'm going to if they're the same Then what I'm going to do is I'm going to basically set the sum at the current index I'm looking for it's going to equal to the maximum sum at the current index and it's going to left some is going to Right some and it's going to equal to where I'm summing from right because if what you're summing from and to is the like the same It's just going to be the same value. So what I mean by that if like let's say I'm summing from Let's say I'm summing from zero to zero so zero and I'm going to sum up instead of anything It'll be just be to zero, right? So that's just the same value of it this so that's just going to return negative one So in that case, we're going to set all the values to just be the whatever value at From at the array at from so that's just going to we're going to set all the values to that and if we just return Okay, so now this part is going to get a little tricky and I might be a little difficult to understand But bear with me. Okay, so what we're going to do is we're going to take them. Otherwise, we're going to take the middle value So basically I'm going to split this up for the array where I'm summing from so Let's say I'm summing from index zero one two three, right zero one two three. I'm gonna get the middle value So let's say I call the function Starting index zero and I'm going up to index one to two, right? I pass in the whole array and I'm going to build my segment tree What I'm going to do is I'm going to take recursively call and I'm going to take the middle value to and I'm going to basically Do the exact same thing of getting some left right max some from the left side And I'm going to do the same thing on the right side. So that's going to give me like recursively calling this over and over again. That's just going to give me the ability to Fill my segment tree and recursively calling left and right so then I have my child's for my nodes So that's what this is for So we get the middle value of where from middle and two and we're just going to build from the left Side from the middle from from the beginning from from to then to middle and then from mid to plus one two To so that what that is is that's going to build my segment tree Cursively calling divide by two and getting from keep this side build a segment here from here And then build a segment you from here and it's going to keep doing that over and over again All right, that's what this part is Because it has build middle and build to okay, so that's going to recursively call this over and over again. All right Then we're going to do something called fill value and fill value. We're going to pass in our index So this is the part where we actually have to fill our values. Okay, so to do that I'm going to show you guys what the fill value does Okay, so the fill value is going to get our the Get the left index And the right index so these are the left children the left and the right and that's two times index plus one And that's two times index plus two. This is just like a math formula that you use to get your left child and right child That's just how the segment trees work. I think a lot of binary surgeries do it this way Anyway, so this is going to be the index from the left child and the right child. Okay So what are we going to do? So if we're going to fill the value of the sum at our current index To equal to this the segment tree on the left side some plus the sum on the right side So what this is going to do like if we're building a segment tree It's basically just going to recursively like sum up from the left side and the right side Right, and that'll be our new sum and then it does that to the parent and to the child So it was like if we have like multiple nodes like this, I don't know This is a binary surgery, but like imagine these are our segments It's gonna sum up from left side to right side. That's what and then that's what the parent knows going to be The parents some is going to be somewhere from left and right and then this part is going to be the parents on the left and right So that's what it's doing. Okay, so that's what the sum is. Okay now We also have to build up the summation from the left side and then summation for the right side so like if remember we When we build up Some some we have to sum from left to right and we also have to sum from right to left because the Problem is asking us could be in any way from left to right or right to left Right. They want to find the maximum sum between the values of indexes zero to two, right? And in our case, it's going to be five and this is something from right to left So what we need to do is we need to build our summation from left to right and right to left So here what we have is we have segment tree at index dot left. This is going to equal to the maximum value From the sum from the left and and the maximum between this either this value or the sum there are total sum that we have plus the Maximum value of the sum from the right left So if I'm summing from okay, this is kind of confusing to understand basically what this is doing is that it's going to take Okay, imagine this is like a tree of Negative one two and three right and I'm basically summing from the left negative one one four So this prefix sum is negative one one four, right? What this is doing for the left Is it's going to get the maximum value summing from the left side all the way to the right? So what that means is that it's probably going to get four in the end, right? It's going to some negative one plus two plus three So what what that what's that doing is that it's going to go to the leaf on the right right child And then it's going to get that left sum Summing from left from that plus the sum of the current parent and we're going to compare that to the sum on the left Right so the the segmentary summing from the left child the sum and then your sum plus the segmentary from the right Way child left some and see whichever is greater. It's going to replace that as a left child. So what that means is that Basically, if we could think about this as like a negative one is on the left side So like let's say two this was two and this is a negative one. This is three, right? This is the this is the this is the Tree so when we're summing from negative one two three what this is going to do is it's going to take the sum from this side and this side Right, it's going to take that this right child's left some so again zooming like This would be like negative one plus two plus three. So those would be like four and this trial of the left side of Negative one and it's going to compare this and this and Whichever is maximum We'll set that as a left sum as a maximum of left some So that's the reason why we need this left left Because we need to find the maximum of the left some and the maximum the right some from something from the left side and the right side So that's what we do here So we have a left is equal to max of left some plus our current sum plus the sum left some of the right And we do the same thing on the right some right so the right some we're going to take the maximum of the sum on the right Max of the summing from the right side and it's going to be the right side of the total sum Plus the left side sum of the right. So what that means is that? Imagine we have other suffix of negative one two three, right? What is this going to do? It's going to take the sum of So let's say is two negative one three. So this time we're summing from the right side It's going to do it's going to compare like this three three plus two would be like five and five plus one is a negative It's going to be four, right? So these are the summing from the right side. What's going to do? It's going to do the summations and it's going to compare the summing from the right side of this and Five and compared both of the summing from the right side of three five and four It's going to set the actual sum from the right side the maximum sum of the right side is going to be five So that's what this is for right Segment tree index dot right is going to be segment tree you right and then segment tree right that some plus segment tree left That's all right Okay, this part is going to be a little more tricky So now once we have the sum from the left side and the right side We need to set our maximum sum to be the maximum value of that So what does that mean? So that's going to what we're going to do is we're going to take our maximum sum from our left side of our left child and The maximum sum on the right child and compare those two something so it's going to compare like It's going to compare the maximum from left side It's going to be like four compare this something from left side would be like four this four and comparing this four with this five Right in order to get that and that's what this part is for but we also have to compare like something from the right sides left left child from left and the rights to the left child's of the right and this is a little confusing because this is basically like This part's kind of comparing like How do I say it's like going between the suffixes so like How do I explain this so let me just clear the board again? Actually, I could just move this so So imagine like we go back to this right Negative one one four four five three so what this is doing is that it's going to compare like the left the left some The right child's left with the left child's right right some so like if we had like Let's say two negative one three right and left child some like the maximum of some of the left child is going to be like I don't know Four right and this would be like Five Because this is a summing from the right side and left side We have to compare these values also four and five to actually get the right values and that's what we do here so that's what this part is for also because if you don't check for this part of Segmentary some from the right sides left and the left sides right You can get things wrong because uh It might not be the case that the maximum value from the left The left side and the right side is the actual maximum value right it could be between both of these parts So that's what this is for the maximum so you have to find the maximum of Lefts child some and the rights to child's right some Also, yeah, that's what that for that's for so once we fill the values we have to fill values Okay, so now once we build our tree up Recursively building our tree up over and over again with this filling the values over and over again What we do need to do is do a query So we're going to query from zero zero negative one n minus one versus the length of the array in our starting value and x and y which is our Which is our index indices where we need to find the maximum sum of so now We're going to go from here Okay, so our starting index is going to be zero We're going to go from from from zero and then two is going to be the length of the array n minus one And then the actual values of left and right that's going to be the indices of the range that we want to find so in our case if we want to find the query between the maximum between the query between X and y right x and y which is like let's say we want to find Maximum sum between here to here right from zero one two So we would pass in one two into this and then ideally this should return like a five because it's two plus three five Yeah But we would pass this in and it would try to calculate that and then our starting index from ever zero So that's what this is for So let's go back to the query So if we're out of range It's just empty and what that means is like if you're like super out of range like Let's say our array was like Zero to three right and then we asked to find four well There's no four here. So like you can't really do anything. It's just be going to be empty Right. So if with what you're trying to find the range is between one and two. Let's say this is out of range You can't really you can't really sum anything, right? So that's what this first if statement is doing if ours listen from and Or else greater than two then we're just gonna return an empty node because you can't really do anything Okay, now if from is greater than or equal to the left side and two is less than or equal to right side so that means like our What this would mean is that it's saying that the What we're querying is actually if What we're querying is less than What we're trying to find then we're just gonna return whatever our segment tree index is of So the reason why we do this is because like if we if we queried so let's say we that's our So this is our Value of our rate right our length of our a zero one two And what if we're querying is that this is actually smaller than where we're actually trying to find So like let's say we had like I don't know Instead of the array, let's say the array was like I don't just one element one and we're trying to query from one to Two right one to two and two doesn't actually exist So in that case, we're just gonna return the current element at the current location right because like you can't really do anything here because like It's just itself. So that's why that's what this is for. It's just gonna return segment tree at the index right Now this part is gonna get a little difficult So now we're gonna get the middle value between from and to and then we're gonna recursively query from the right side of the from the left child That's an index times two plus one and then we still believe it from in middle and left and right So if the right side is like less than or equal to the middle You know, we're gonna recursively query the left side, right? So if we're querying on the right side is like less than or equal to the middle. So like if Let's say I was querying. I Don't know the right side is this right Let's I'm trying to query from here and it's less than the middle of the middle is too, right? Then what I'm gonna do is I'm gonna recursively call on the left side and get the sums from the values from the left side So that's what this is doing. Okay, if left side is greater than middle. So let's say I'm trying to query values from here From here, let's say this was what my left side that I'm trying to query and then this is of my actual array 012 right Then we're gonna recursively call on the right side and try to query from the right side So that's what this is for. So that's what we query on the Index times two plus one and then we're gonna move our shift our middle to the middle plus one and then to left and right So that's what where this is doing So it's basically just recursively calling on the left side and the right side until we get our our queries And that's what we're doing here. I get the node from left child in the right child And I'm just recursively calling from the left side and the right side again regardless So yeah, that's how I do the here and then I combine both of the values from left and right So for that that's right here basically to combine the two segments from left and the right For the basically we're gonna create a new node and we're gonna sum up the two sums from left and right and Then what we're gonna do is we're gonna get the maximum of the left sum and that's just gonna be the maximum of the values on the left side and then the sum of our current sum plus the Left sums value on the right side Yeah, left sums are on the right side and then Then we need to find the sum from the right side So for that we're gonna get the maximum value on the right side and then we're gonna do Plus the left sum of the value on the right left sides, right? Okay So that's what this right is for and then then we need to do max Get the maximum for that we do the same thing we need to get the maximum of the left and right Maximum value for that and then we add the B's left and then A's right. So that's what we do that here This A and B are just like left left child left child in the right child Okay, so yeah, then we return the combination and that's just going to merge the two The two segments together and then you're gonna have your actual Query tree in the end. So then you were to see out the query So that's basically that's basically how the whole code and how the gist of how to do this problem You need to maintain The sum from the left side and the right side and then you need to make sure you store like the right Maximum for that and then in the end we just return the maximum So yeah, so while you're building up your tree recursively going from left in the right Yeah, I hope you guys enjoy this video where come subscribe. It's just kind of hard to make but yeah, I'm really tired. Peace