多種操作的懶惰標記
就算有很多種操作,線段樹一樣能搞定!
區間修改與懶惰標記
Segment Tree Beats
區間加值、區間賦值
操作的順序?
void push(int idx, int l, int r){
int m = (l+r)/ 2;
if(tag_assign[idx]!=-1){
tr[idx<<1] = tag_assign[idx] * (m-l+1);
tr[idx<<1|1] = tag_assign[idx] * (r-m);
tag_assign[idx<<1] = tag_assign[idx];
tag_assign[idx<<1|1] = tag_assign[idx];
tag_add[idx<<1] = tag_add[idx<<1|1] = 0;
tag_assign[idx] = -1;
}
if(tag_add[idx]){
tr[idx<<1] += tag_add[idx] * (m-l+1);
tr[idx<<1|1] += tag_add[idx] * (r-m);
tag_add[idx<<1] += tag_add[idx];
tag_add[idx<<1|1] += tag_add[idx];
tag_add[idx] = 0;
}
}
void add(int ql, int qr, int val, int idx, int l, int r){
if(l!=r) push(idx, l, r);
if(ql <= l && r <= qr){
tr[idx] += val * (r-l+1);
tag_add[idx] += val;
return;
}
int m = (l+r)/2;
if(qr > m) add(ql, qr, val, idx*2+1, m+1, r);
if(ql <= m) add(ql, qr, val, idx*2, l, m);
tr[idx] = combine(tr[idx<<1],tr[idx<<1|1]);
}
void assign(int ql, int qr, int val, int idx, int l, int r){
if(l!=r) push(idx, l, r);
if(ql <= l && r <= qr){
tr[idx] = val * (r-l+1);
tag_assign[idx] = val;
tag_add[idx] = 0; //如果修改了值,那就不必再下推上一個加值的操作了
return;
}
int m = (l+r)/2;
if(qr > m) assign(ql, qr, val, idx*2+1, m+1, r);
if(ql <= m) assign(ql, qr, val, idx*2, l, m);
tr[idx] = combine(tr[idx<<1],tr[idx<<1|1]);
}區間加值、區間最大值
Segment Tree BeatsLast updated