单点更新
const int N = 100005;
LL a[N]; //a[N]储存原数组
LL lazy[N << 2]; //lazy用来记录该节点的每个数值应该加多少
int n, q;
struct Tree
{
int l, r;
LL sum;
int mid()
{
return (l + r) >> 1;
}
}tree[N<<2];
void PushUp(int rt)
{
tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
}
void PushDown(int rt,int m)
{
if (lazy[rt])
{
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
tree[rt << 1].sum += lazy[rt] * (m - (m >> 1));
tree[rt << 1 | 1].sum += lazy[rt] * (m >> 1);
lazy[rt] = 0;
}
}
void build(int l, int r, int rt)
{
tree[rt].l = l;
tree[rt].r = r;
lazy[rt] = 0;
if (l == r)
{
tree[rt].sum = a[l];
return;
}
int m = tree[rt].mid();
build(l, m, (rt << 1));
build(m + 1, r, (rt << 1 | 1));
PushUp(rt);
}
void update(LL c, int l, int r, int rt)
{
if (tree[rt].l == l&&tree[rt].r==r)
{
lazy[rt] += c;
tree[rt].sum += c*(r - l + 1);
return;
}
if (tree[rt].l == tree[rt].r)return;
int m = tree[rt].mid();
PushDown(rt, tree[rt].r - tree[rt].l + 1);
if (r <= m)update(c, l, r, rt << 1);
else if (l > m)update(c, l, r, rt << 1 | 1);
else
{
update(c, l, m, rt << 1);
update(c, m + 1, r, rt << 1 | 1);
}
PushUp(rt);
}
LL Query(int l, int r, int rt)
{
if (l == tree[rt].l&&r == tree[rt].r)
{
return tree[rt].sum;
}
int m = tree[rt].mid();
PushDown(rt, tree[rt].r - tree[rt].l + 1);
LL res = 0;
if (r <= m)res += Query(l, r, rt << 1);
else if (l > m)res += Query(l, r, rt << 1 | 1);
else
{
res += Query(l, m, rt << 1);
res += Query(m + 1, r, rt << 1 | 1);
}
return res;
}
区间更新
很奇怪为什么一直贴不过来 所以直接贴网址了…