线段树
typedef long long ll;
const int maxn = 1e5 + 5;
int a[maxn];
ll tree[maxn * 4];
int flag[maxn * 4];
传入各函数的结点node应该为1(比如下面的代码)。
传入结点为1的关系:
左儿子:2*node
右儿子:2*node+1
如果传入结点为0的话,结点的关系就变成了
左儿子:2*node+1
右儿子:2*node+2
void build(int *a,int node,int l,int r)
{
if (l == r)
{
tree[node] = a[l];
return ;
}
int mid = (l + r) / 2;
build(a, node * 2, l, mid);
build(a, node * 2 + 1, mid + 1, r);
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}
void pushdown(int k, int l, int r)
{
int mid = (l + r) / 2;
flag[2 * k] += flag[k];
tree[2 * k] += ((mid - l) + 1) * (ll)flag[k];
flag[2 * k + 1] += flag[k];
tree[2 * k + 1] += (r - mid) * (ll)flag[k];
flag[k] = 0;
}
void updata_single(int node, int l, int r, int x, int num)
{
if (l == x && r == x)
{
tree[node] = num;
return;
}
int mid = (l + r) / 2;
if (mid >= x)
updata_single(node * 2, l, mid, x, num);
else updata_single(node * 2 + 1, mid + 1, r, x, num);
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}
void updata_region(int node, int l, int r, int tl, int tr, int num)
{
if (tl<=l && r <= tr)
{
tree[node] = num * (ll)(r - l + 1);
flag[node] += num;
return;
}
if (flag[node]) pushdown(node, l, r);
int mid = (l + r) / 2;
if (tl <= mid) updata_region(node * 2, l, mid, tl, tr, num);
if (tr > mid) updata_region(node * 2 + 1, mid + 1, r, tl, tr, num);
tree[node] = tree[node * 2] + tree[node * 2 + 1];
}
ll query(int node, int l, int r, int tl, int tr)
{
if (tl<=l && r <= tr) return tree[node];
if (flag[node]) pushdown(node, l, r);
ll sum = 0;
int mid = (l + r) / 2;
if (tl <= mid) sum += query(node * 2, l, mid, tl, tr);
if (tr > mid) sum += query(node * 2 + 1, mid + 1, r, tl, tr);
return sum;
}