DAY1 (线段树)

线段树的内涵:用数组模拟树,每个节点掌控一个L,R区间,该节点的值为L,R的“总”信息;

         每个节点有俩个左右孩子;

线段树的适用条件: 总信息可以由左孩子以及右孩子的总信息加工而成,而这个加工函数就是

  up(i),以及 search()的关键 

线段树的修改理解:不断通过二分,向下找出所有包含目标子区间的节点,然后对这个节点的值进行修改;

线段树查询理解:不断通过二分找到所有子区间,利用加工原理,汇合出总答案;

线段树区间修改原理: 如果一个区间修改完全覆盖一个子区间,那么不必继续向下搜索,而是懒住,一但有向下访问,那么一层一层下放;即只有区间被访问子区间才需下放;

线段树的关键: 关键在于加工函数以及修改逻辑;

加工:节点信息到底怎样由孩子信息加工而成;区间和,则孩子信息和,区间最大值则孩子最大值,

修改:区间增减,区间乘,区间重置,

代码:

void up(int i){
    tree[i]=tree[ls]+tree[rs];
}

int s(int i,int jl,int jr,int l,int r){
    if(l>=jl&&r<=jr)return tree[i];
    down(i,l,r);
    int mid=(l+r)/2;
    int res=0;
    if(mid>=l)res+=s(ls,jl,jr,l,mid);
    if(mid<r)res+=(rs,jl,jr,mid+1,r);
    return res;
}// 可见 主要逻辑在于 加工函数

void add(int i,int jl,int jr,int l,int r,int k){
    if(l>=jl&&r<=jr){
        tree[i]+=(r-l+1)*k;
        lazy[i]+=k;
        return;
    }
    down(i,l,r);
    int mid=(l+r)/2;
    if(mid>=l)add(ls,jl,jr,l,mid,k);
    if(mid<r)add(rs,jl,jr,mid+1,r,k);
    up(i);
}

 void down(int i,int l,int r){
     if(lazy[i]){
         int mid=(l+r)/2;
          add(ls,l,r,l,mid,lazy[i]);
         add(rs,l,r,mid+1,r,lazy[i]);
         lazy[i]=0;
     }
 }// 主要逻辑在于修改逻辑

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值