线段树 与 树状数组进阶
通过观察 rqy 的题解,发现可以考虑只有区间推平操作的历史和问题。
现有问题:给定一个序列,操作要求区间推平,维护历史版本和。
考虑在线段树上维护 \(s,hs,l\) 表示区间和、区间历史版本和、区间长度。
\((tg,htg,upd)\) 表示标记队列。
考虑一个线段树节点加上一个标记队列:
先考虑标记队列是否有标记。如果有标记,就推平,考虑原来的节点信息是否有标记,如果有标记,就把新来 \(upd\) 转移到 \(htg\) 里面,否则继续下传 \(upd\) 标记。如果标记队列没有标记,那么直接加上区间和即可
struct node{
LL hs,s,tg,htg,upd; int l;
void addt(LL tg2,LL htg2,LL upd2){
if(tg2){
hs+=upd2*s+htg2*l; htg+=htg2; s=tg2*l;
if(tg) htg+=upd2*tg;
else upd+=upd2;
tg=tg2;
}
else {
hs+=upd2*s;
if(tg) htg+=upd2*tg;
else upd+=upd2;
}
}
}
说不定可以即支持区间推平和区间加,即考虑在加法标记队列后面维护一个推平标记队列,如果有加法加进来就考虑变成标记队列。

浙公网安备 33010602011771号