# 線段樹
* 一直分兩半,再一個個合起來
* 二元樹陣列需開到**4n**(有證明)
* 以下樹的陣列是1-indexed
```cpp=
#define N 100000
int tree[N<<2]={0};
int num[N];
void build(int v, int l, int r){
if (l == r)
tree[v]=num[l];
else{
int mid = (l+r) >> 1;
build(v*2, l, mid);
build(v*2+1, mid+1, r);
tree[v]=tree[v*2]+tree[v*2+1];
}
}
void update(int v, int x, int pos, int l, int r){
if(l==r)
tree[v]=x;
else{
int mid=(l+r)>>1;
if(pos<=mid) update(2*v, pos, l, mid);
else update(2*v+1, pos, mid+1, r);
tree[v]=tree[2*v]+tree[2*v+1];
}
}
int query(int v, int l, int r, int ql, int qr){
if(ql>qr)
return 0;
if(l==ql && r==qr)
return tree[v];
int mid=(l+r)>>1;
return query(2*v, l, mid, ql, min(qr, mid))+query(2*v+1, mid+1, r, max(ql, mid+1), qr);
}
```
懶標
---
* 用於區間和
* modify變成跟區間查詢很像,如果要加的區間完全涵蓋某節點的區間,就對那個節點標記要加的值(自己也加起來)
* 而下次要區間查詢或修改,如果遇到又標記的節點,就把它往下推到兩個子節點,並初始化目前節點的標記
```cpp=
#include <bits/stdc++.h>
#define EB emplace_back
#define vci vector<int>
#define PII pair<int,int>
#define F first
#define S second
#define rep(X, a,b) for(int X=a;X<b;++X)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) (int)(a).size()
#define NL "\n"
#define LL long long
using namespace std;
LL tree[5*500000], num[500010], tag[5*500000]={0};
void push(int v, int l, int r){
int mid=(l+r)>>1;
tag[2*v]+=tag[v];
tag[2*v+1]+=tag[v];
tree[2*v]+=(mid-l+1)*tag[v];
tree[2*v+1]+=(r-mid)*tag[v];
tag[v]=0;
}
void build(int v, int l, int r){
if(l==r) tree[v]=num[l];
else{
int mid=(l+r)>>1;
build(2*v, l, mid);
build(2*v+1, mid+1, r);
tree[v]=tree[2*v]+tree[2*v+1];
}
}
void modify(int v, int l, int r, int ul, int ur, LL x){
if(l==ul && r==ur){
tag[v]+=x;
tree[v]+=(r-l+1)*x;
return;
}
if(tag[v]) push(v, l, r);
int mid=(l+r)>>1;
if(ur<=mid) modify(2*v, l, mid, ul, ur, x);
else if(ul>mid) modify(2*v+1, mid+1, r, ul, ur, x);
else{
modify(2*v, l, mid, ul, mid, x);
modify(2*v+1, mid+1, r, mid+1, ur, x);
}
tree[v]=tree[2*v]+tree[2*v+1];
}
LL query(int v, int l, int r, int ql, int qr){
if(l==ql && r==qr) return tree[v];
if(tag[v]) push(v, l, r);
int mid=(l+r)>>1;
if(qr<=mid) return query(2*v, l, mid, ql, qr);
else if(ql>mid) return query(2*v+1, mid+1, r, ql, qr);
return query(2*v, l, mid, ql, mid)+query(2*v+1, mid+1, r, mid+1, qr);
}
```