//动态线段树
public class DynamicSegTree {
private Map<Integer, Integer> tree;//线段树,表示某节点的值
private Map<Integer, Integer> lazy;//懒标记
private int N;//最大范围
public DynamicSegTree() {
tree = new HashMap<Integer, Integer>();
lazy = new HashMap<Integer, Integer>();
N= (int)1e9;
}
//区间修改
public void update(int l,int r,int val){
if(l>r) return;
update(l,r,1,N,1,val);
}
private void update( int l, int r,int curl, int curr, int node,int val) {
//区间无交集
if (curl>r||curr<l)
return;
//当前区间在目标区间内
if (l<=curl&&curr<=r) {
tree.put(node,val);//更新当前节点
if(curl<curr) lazy.put(node, val);
} else {//当前区间与目标区间存在交集
int mid = (curl + curr) >> 1;
if(lazy.getOrDefault(node,0)!=0)
pushDown(node,lazy.get(node));//向下传递标记
//分割处理区间
update( l, r, curl, mid,2 * node,val);
update(l, r, mid+1, curr, 2 * node + 1,val);
//更新当前节点
tree.put(node,Math.max(tree.getOrDefault(2 * node, 0),
tree.getOrDefault(2 * node + 1, 0)));
}
}
//将标记向下一层传递
private void pushDown(int node,int _lazy){
lazy.put(node*2,_lazy);
lazy.put(node*2+1,_lazy);
tree.put(node*2,_lazy);
tree.put(node*2+1,_lazy);
lazy.put(node,0);
}
//区间查询
public int query(int l,int r){
if(l>r) return -1;
return query(l,r,1,N,1);
}
private int query(int l,int r,int curl,int curr,int node){
//不在目标区间
if(curl>r||curr<l)
return 0;
//在目标区间
if(l<=curl&&curr<=r)
return tree.getOrDefault(node,0);
//部分有交集,分割区间处理
int mid=(curl+curr)>>1;
if(lazy.getOrDefault(node,0)!=0)
pushDown(node,lazy.get(node));
return Math.max(query(l,r,curl,mid,node*2),query(l,r,mid+1,curr,node*2+1));
}
}
public List<Integer> fallingSquares(int[][] positions) {
List<Integer> ans=new ArrayList<>();
DynamicSegTree t=new DynamicSegTree();
for(int[] position:positions){
int max=t.query(position[0],position[0]+position[1]-1);//查询方块区间最大值
//更新方块区间
t.update(position[0],position[0]+position[1]-1,max+position[1]);
ans.add(t.query(1,t.N));
}
return ans;
}
动态线段树leetcode.699
最新推荐文章于 2023-01-29 17:10:43 发布