區間更新和懶惰標記的線段樹


區間更新和懶惰標記的線段樹

前言

普通版本的線段樹進行的是 單點更新 和 區間查詢 . 對於帶有 懶惰標記 的線段樹, 則可以進行 區間更新.

懶惰標記的意義

代表了這個結點的值已經被更新過了, 但是沒有進行子樹的結點值更改操作, 用lazy數組標記一下.
所以, 每次進行值的更新和查詢操作, 每到一個有 lazy 標記的結點, 必須進行向下更新.

代碼

//區間替換
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

#define max(a,b) (a>b)?a:b
#define min(a,b) (a>b)?b:a
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define LL long long
const int maxn = 100100;
using namespace std;

int lazy[maxn<<2];
int sum[maxn<<2];

void PushUp(int rt)//由左孩子、右孩子向上更新父節點
{
    sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}

void PushDown(int rt,int m) //向下更新
{
  if (lazy[rt]) //懶惰標記
  {
    lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
    sum[rt<<1] = (m - (m >> 1)) * lazy[rt];
    sum[rt<<1|1] = ((m >> 1)) * lazy[rt];
    lazy[rt] = 0;
  }
}

void build(int l,int r,int rt)//建樹
{
  lazy[rt] = 0;

  if (l== r)
  {
    scanf("%d",&sum[rt]);
    return ;
  }
  int m = (l + r) >> 1;
  build(lson);
  build(rson);
  PushUp(rt);
}

void update(int L,int R,int c,int l,int r,int rt)//更新
{
  //if(L>l||R>r) return;
  if (L <= l && r <= R)
  {
    lazy[rt] = c;
    sum[rt] = c * (r - l + 1);
    //printf("%d %d %d %d %d\n", rt, sum[rt], c, l, r);
    return ;
  }
  PushDown(rt , r - l + 1);
  int m = (l + r) >> 1;
  if (L <= m) update(L , R , c , lson);
  if (R > m) update(L , R , c , rson);
  PushUp(rt);
}

LL query(int L,int R,int l,int r,int rt)
{
  if (L <= l && r <= R)
  {
    //printf("%d\n", sum[rt]);
    return sum[rt];
  }
  PushDown(rt , r - l + 1);
  int m = (l + r) >> 1;
  LL ret = 0;
  if (L <= m) ret += query(L , R , lson);
  if (m < R) ret += query(L , R , rson);
  return ret;
}

int main()
{
  int  n , m;
  char str[5];

  while(scanf("%d%d",&n,&m))
  {
    build(1 , n , 1);
    while (m--)
    {
      scanf("%s",str);
      int a , b , c;
      if(str[0]=='T')
      {
        scanf("%d%d%d",&a,&b,&c);
        update(a , b , c , 1 , n , 1);
      }
      else if(str[0]=='Q')
      {
        scanf("%d%d",&a,&b);
        cout<<query(a,b,1,n,1)<<endl;
      }
    }
  }

  return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM