区改区查标记永久化线段树

写完树剖之后发现还没有讲过区改区查线段树。。。

标记永久化线段树的用处:

支持区改区查,嗯,就这样。(不过听很多dalao说这种线段树有利于写主席树)

算法核心思路:

对于一段区间加,假如它把线段树上的一部分完全包涵,那么我们就把它“永久”的加在这部分上,否则就加在另外一个神奇的地方,这个神奇的地方只有当询问区间将其完全包涵才能加。

这样我们就把区间加变成了log级别的。

代码实现:

procedure update(k,l,r,x,y,z:longint);
var
    mid:longint;
begin
    if (l>=x)and(r<=y) then
    begin
        add_sum[k]:=(add_sum[k]+z)mod p; exit;               //完全包涵,把标记永久化。
    end;
    sum[k]:=(sum[k]+(min(r,y)-max(l,x)+1)*z mod p)mod p;     //加到一个神奇的地方(我们可以叫它半永久标记,好吧我瞎掰的。。。)
    mid:=(l+r)>>1;
    if x<=mid then update(k*2,l,mid,x,y,z);                  //像普通线段树的查询操作一样继续更新其他节点,直到需要我们修改的区间全部被永久化为止
    if y>mid then update(k*2+1,mid+1,r,x,y,z);
end;
function query(k,l,r,x,y:longint):longint;
var
    mid:longint;
begin
    if (l>=x)and(r<=y) then exit((sum[k]+(r-l+1)*add_sum[k]mod p)mod p);
    mid:=(l+r)>>1;
    query:=(min(r,y)-max(l,x)+1)*add_sum[k]mod p;
    if x<=mid then query:=(query+query(k*2,l,mid,x,y))mod p;
    if y>mid then query:=(query+query(k*2+1,mid+1,r,x,y))mod p;
end;

转载于:https://www.cnblogs.com/WR-Eternity/p/9901158.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值