普通區間修改和查詢 (帶懶惰标記)模闆
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+50;
struct node
{
int l, r;//區間左右端點
int sum;//區間資訊, 可以是最值、 區間和、等等
int lazy;//懶惰标記
}Segtr[maxn*4];// 開4倍空間, 這個是大佬們計算出的
void pushdown(int rt)// 懶惰标記下壓函數
{
/********
此處有更新操作, 按照題意
***********/
//下壓标記
Segtr[rt*2+1].lazy = Segtr[rt].lazy;
Segtr[rt*2+2].lazy = Segtr[rt].lazy;
Segetr[rt].lazy = 0;
}
void pushup(int rt)
{
Segtr[rt].sum = Segtr[rt*2+1].sum+Segtr[rt*2+2].sum;//回溯更新操作, 按照題意
}
void build(int l, int r, int rt)// 分别表示區間的左右端點, 和區間對應結點的編号
{
//初始化
Segtr[rt].l = l;
Segtr[rt].r = r;
Segtr[rt].lazy = 0;
Segtr[rt].sum = 0;
if(l == r)return;//遞歸到葉子結點傳回
int mid = (l+r)/2; //可以換成(l+r)>>1;
build(l, mid, rt*2+1);//建立左子樹
build(mid+1, r, rt*2+2);//建立右子樹
pushup(rt);// 回溯維護父結點
}
void update(int L, int R, int rt, int v)//分别表示要更新區間額左右端點 和對應的結點編号, 和更新的值
{
int l = Segtr[rt].l;
int r = Segtr[rt].r;
if(l == L&& r == R)// 找到要更細的直接區間,将其更新, 然後打上标記
{
Segtr[rt].sum += (R-L+1)*add;
Segtr[rt].lazy +=add;
return;
}
if(Segtr[rt].lazy) pushdown(rt); //如果有标記就下壓标記
int mid = (l+r)/2;
if(R <= mid) update(L, R, rt*2+1, add);
else if(L > mid) update(L, R, rt*2+2, add);
else
{
update(L, mid, rt*2+1, add);
update(mid+1, R, rt*2+2, add);
}
pushup(rt); //回溯維護父親
}
int query(int L, int R, int rt)// 查詢函數
{
int res = 0;
int l = Segtr[rt].l;
int r = Segtr[rt].r;
if(l == L && r == R)
{
return Segtr[rt].sum;
}
if(Segtr[rt].lazy)pushdown(rt);
int mid = (l+r)/2;
if(R <= mid)res+=query(L, R, rt*2+1);
else if(L > mid)res+=query(L, R, rt*2+2);
else
{
res+=query(L, mid, rt*2+1);
res+=query(mid+1, R, rt*2+2);
}
return res;
}
int main()
{
return 0;
}