import java.util.ArrayList;
import java.util.List;
class Solution {
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.fallingSquares(new int[][]{
{9,7},{1,9},{3,1}
}));
}
public List<Integer> fallingSquares(int[][] positions) {
Seg seg = new Seg(1,101000000);
List<Integer> ans = new ArrayList<>();
for(int[] position:positions){
int l = position[0];
int r = position[0] +position[1] - 1;
int curr = seg.query(l,r);
seg.update(l,r,curr+position[1]);
ans.add(seg.height);
}
return ans;
}
class Seg{
int cl,cr;
Seg left,right;
int lazy;
int height;
public Seg(int l,int r){
this.cl = l;
this.cr = r;
this.height = 0;
}
public int query(int l,int r){
if( cl == l && cr == r){
return this.height;
}
pushdown();
int mid = (cl+cr)/2;
if( r<=mid){
return this.left.query(l,r);
}
else{
if( l > mid){
return this.right.query(l,r);
}else{
return Math.max(this.left.query(l,mid),this.right.query(mid+1,r));
}
}
}
public void pushdown() {
int mid = (cl+cr)/2;
if( this.left == null){
this.left = new Seg(cl,mid);
}
if(this.right == null){
this.right = new Seg(mid+1,cr);
}
if(this.lazy == 0) return;
this.left.lazy = this.lazy; this.right.lazy = this.lazy;
this.left.height = this.lazy;
this.right.height = this.lazy;
this.lazy = 0;
}
public void pushup(){
this.height = Math.max(this.left.height,this.right.height);
}
public void update(int l,int r,int height){
if(cl == l && cr == r){
this.height = height;
this.lazy = height;
return;
}
pushdown();
int mid = (cl+cr)/2;
if(r<=mid){
this.left.update(l,r,height);
}else{
if(l>mid){
this.right.update(l,r,height);
}else{
this.left.update(l,mid,height);
this.right.update(mid+1,r,height);
}
}
pushup();
}
}
}