P3372 模板 線段樹 1

2021-09-18 06:31:16 字數 1293 閱讀 9818

#include#includeusing namespace std;

typedef long long ll;

ll n, m, ans, x, y, op, val;//因為下面有的函式需要用到x,y,val值,懶得傳參,故直接寫為全域性變數

const int n = 100000;

struct nodetree[n<<2];//一般會開為給定最大陣列的4倍

//構建樹

void build(int k, int l, int r)

ll mid=(tree[k].l+tree[k].r)>>1;

build(k<<1, l, mid);//構建左子樹 即(2*k)

build(k<<1|1, mid+1, r);//構建右子樹 即(2*k+1)

//因為是遞迴構造樹,所以求該k節點的sum即可用以下式子直接求出(相當於遞迴到葉子結點,然後從葉子結點往上更新父節點的值)

tree[k].sum = tree[k<<1].sum+tree[k<<1|1].sum;

}//向下傳遞懶惰標記,傳遞完後該節點的懶惰標記歸0

void pushdown(ll k)

void query(int k)//求某一區間的和

//(x, y)不包含同一區間,則將懶惰標記向下傳給左右孩子

if(tree[k].lazy)

pushdown(k);

ll mid = (tree[k].l+tree[k].r)>>1;

if(x <= mid)//有一部分位於左子樹

query(k<<1);

if(y>mid)//有一部分位於右子樹

query(k<<1|1);

}//區間更新

void updatesq(ll k)

//因為(x, y)不能完全包含該節點的區間,將懶惰標記傳給他的孩子,繼續向下更新

if(tree[k].lazy)

pushdown(k);

ll mid=(tree[k].l+tree[k].r)>>1;

if(x <= mid)

updatesq(k<<1);

if(y > mid)

updatesq(k<<1|1);

//更新父節點方法與build裡的一樣

tree[k].sum=tree[k<<1].sum+tree[k<<1|1].sum;

}int main()

else

}return 0;

}

P3372 模板 線段樹 1

線段樹學習 這個題來看,線段樹分為建樹,更新,查詢。1.建樹 void build ll p,ll l,ll r ll mid l r 1 build lson p l,mid build rson p mid 1,r push up sum p void push up sum ll p 這段 的...

P3372 模板 線段樹 1

題目描述 如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.求出某區間每乙個數的和 輸入輸出格式 輸入格式 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含3或4個整數...

P3372 模板 線段樹 1

如題,已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.求出某區間每乙個數的和 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含3或4個整數,表示乙個操作,具體如下 操作1 ...