zoukankan      html  css  js  c++  java
  • 【模板】线段树区间修改

    区间修改:

    区间修改过程类似于区间询问,例如将[ul, ur]内的所有元素都加上v,则进行如下操作:

    当当前区间被区间[ul, ur]所包含时,

      当前的节点值加上区间长度(r - l  + 1)乘以v

      对当前节点的lazy-tag加上v,修改结束

    否则,将当前节点的lazy-tag下传,分别修改左孩子和右孩子(一定条件下),然后更新此节点的值

    lazy-tag下传:

    如果当前节点没有lazy-tag,直接return

    否则:1.  将左孩子右孩子分别加上lazy-tag * 区间长度的值

        2.  左孩子和右孩子的懒惰标记加上lazy-tag

        3.  当前节点的lazy-tag清零

    注意区间询问的时候也要lazy-tag下传

    【代码:】

     1 //线段树区间修改
     2 #include<iostream>
     3 #include<cstdio>
     4 using namespace std;
     5 
     6 const int MAXN = 100000 + 1;
     7 
     8 int n, m, a[MAXN];
     9 struct Segment {
    10     long long sum, lazy;
    11     Segment() {
    12         sum = lazy = 0;
    13     }
    14 }t[MAXN << 2];
    15 
    16 void Build(int o, int l, int r) {
    17     if(l == r) t[o].sum = a[l];
    18     else {
    19         int mid = (l + r) >> 1;
    20         Build(o << 1, l, mid);
    21         Build(o << 1|1, mid + 1, r);
    22         t[o].sum = t[o << 1].sum + t[o << 1|1].sum;
    23     }
    24 }
    25 void down(int o, int len) {
    26     if(!t[o].lazy) return;
    27     t[o << 1].sum += t[o].lazy * (len - (len >> 1));
    28     t[o << 1|1].sum += t[o].lazy * (len >> 1);
    29     t[o << 1].lazy += t[o].lazy;
    30     t[o << 1|1].lazy += t[o].lazy;
    31     t[o].lazy = 0;
    32 }
    33 void Update(int o, int l, int r, int ul, int ur, int v) {
    34     if(ul <= l && r <= ur) {
    35         t[o].sum += (r - l + 1) * v;
    36         t[o].lazy += v;
    37     }
    38     else {
    39         down(o, r - l + 1);
    40         int mid = (l + r) >> 1;
    41         if(ul <= mid) Update(o << 1, l, mid, ul, ur, v);
    42         if(ur > mid) Update(o << 1|1, mid + 1, r, ul, ur, v);
    43         t[o].sum = t[o << 1].sum + t[o << 1|1].sum;
    44     }
    45 }
    46 long long Query(int o, int l, int r, int ql, int qr) {
    47     if(ql <= l && r <= qr) {
    48         return t[o].sum;
    49     }
    50     int mid = (l + r) >> 1;
    51     long long ret = 0;
    52     down(o, r - l + 1);
    53     if(ql <= mid) ret += Query(o << 1, l, mid, ql, qr);
    54     if(qr > mid) ret += Query(o << 1|1, mid + 1, r, ql, qr);
    55     return ret;
    56 }
    57 int main() {
    58     scanf("%d%d", &n, &m);
    59     for(int i = 1; i <= n; ++i)
    60         scanf("%d", &a[i]);
    61     Build(1, 1, n);
    62     while(m--) {
    63         int fl, x, y;
    64         scanf("%d%d%d", &fl, &x, &y);
    65         if(fl == 1) {
    66             int k;
    67             scanf("%d", &k);
    68             Update(1, 1, n, x, y, k);
    69         }
    70         else printf("%lld
    ", Query(1, 1, n, x, y));
    71     }
    72 }

    模板测试题目传送门

  • 相关阅读:
    Spring boot 启动图片
    Spring Cloud 从入门到入门
    理解错误的 Arrays.asList()
    git github 对代码的管理
    【POJ 2154】Color
    CodeForces
    CodeForces
    CodeForces
    CodeForces
    [数据结构]Hash Table(哈希表)
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9044841.html
Copyright © 2011-2022 走看看