Java 44ms solution. Segment tree with lazy propagation
\nclass Solution {\n    public static class SegmentTree {\n        TreeNode root;\n        public class TreeNode {\n            TreeNode left;\n            Tree
```\nclass Solution {\n    public static class SegmentTree {\n        TreeNode root;\n        public class TreeNode {\n            TreeNode left;\n            TreeNode right;\n            int leftBound;\n            int rightBound;\n            int lazy;\n            int max;\n            public TreeNode(int l,int r,int m) {\n                leftBound = l;\n                rightBound = r;\n                lazy = 0;\n                max = m;\n            }\n            public int getMid(){\n                return leftBound + (rightBound-leftBound)/2;\n            }\n            public TreeNode getLeft() {\n                if (left == null) left = new TreeNode(leftBound,getMid(),0);\n                return left;\n            }\n            public TreeNode getRight() {\n                if (right == null) right = new TreeNode(getMid()+1,rightBound,0);\n                return right;\n            }\n        }\n        public SegmentTree() {\n            root = new TreeNode(0,Integer.MAX_VALUE,0);\n        }\n        public int getMax(){\n            return root.max;\n        }\n        public TreeNode update(int l,int r,int val) {\n            return update(root,l,r,val);\n        }\n        public TreeNode update(TreeNode node,int l,int r,int val) {\n            if (node.lazy != 0) {\n                node.max = node.lazy;\n                if (node.leftBound != node.rightBound) {\n                    node.getLeft().lazy = node.lazy;\n                    node.getRight().lazy = node.lazy;\n                }\n                node.lazy = 0;\n            }\n            if(node.rightBound < node.leftBound || r < node.leftBound || l > node.rightBound) return node;\n            if(node.leftBound >= l && node.rightBound <= r ) {\n                node.max = val;\n                if (node.leftBound != node.rightBound) {\n                    node.getLeft().lazy = val;\n                    node.getRight().lazy = val;\n                }\n                return node;\n            }\n            node.left = update(node.getLeft(),l,r,val);\n            node.right = update(node.getRight(),l,r,val);\n            node.max = Math.max(node.left.max,node.right.max);\n            return node;\n        }\n        public int query(int l,int r) {\n            return query(root,l,r);\n        }\n        public  int query(TreeNode node,int l,int r) {\n            if(node.rightBound < node.leftBound || r < node.leftBound || l > node.rightBound) return 0;\n            if (node.lazy != 0) {\n                node.max = node.lazy;\n                if (node.leftBound != node.rightBound) {\n                    node.getLeft().lazy = node.lazy;\n                    node.getRight().lazy = node.lazy;\n                }\n                node.lazy = 0;\n            }\n            if(node.leftBound >= l && node.rightBound <= r ) return node.max;\n            int q1 = query(node.getLeft(),l,r);\n            int q2 = query(node.getRight(),l,r);\n            return Math.max(q1,q2);\n        }\n\n    }\n    public List<Integer> fallingSquares(int[][] positions) {\n        List<Integer> res = new ArrayList<Integer>();\n        SegmentTree segmentTree = new SegmentTree();\n        for(int[] p: positions) {\n            int h = segmentTree.query(p[0],p[0]+p[1]-1);\n            segmentTree.update(p[0],p[0]+p[1]-1,h+p[1]);\n            res.add(segmentTree.getMax());\n        }\n        return res;\n    }\n    \n}\n```
[]