题目:动态求连续区间和
树状数组
cpp
#include <cstdio>
#define LL long long
const LL N = 100010;
LL n, m, a[N], tr[N];
LL lowbit(LL x)
{
return x & -x;
}
void add(LL x, LL y)
{
for (LL i = x; i <= n; i += lowbit(i))
tr[i] += y;
}
LL query(LL x)
{
LL res = 0;
for (LL i = x; i >= 1; i -= lowbit(i))
res += tr[i];
return res;
}
int main()
{
scanf("%lld%lld", &n, &m);
for (LL i = 1; i <= n; i ++ )
{
scanf("%lld", &a[i]);
add(i, a[i]);
}
while (m -- )
{
LL k, a, b;
scanf("%lld%lld%lld", &k, &a, &b);
if (!k)
printf("%lld\n", query(b) - query(a - 1));
else
add(a, b);
}
return 0;
}
线段树
cpp
#include <cstdio>
#define LL long long
const LL N = 100010;
LL n, m, a[N];
struct
{
LL l;
LL r;
LL sum;
}
tr[4 * N];
void pushup(LL u)
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void build(LL u, LL l, LL r)
{
if (l == r)
tr[u] = {l, r, a[l]};
else
{
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(LL u, LL x, LL y)
{
if (tr[u].l == tr[u].r)
tr[u].sum += y;
else
{
int mid = tr[u].l + tr[u].r >> 1;
if (tr[u].l <= x && x <= mid) modify(u << 1, x, y);
else modify(u << 1 | 1, x, y);
pushup(u);
}
}
LL query(LL u, LL l, LL r)
{
LL sum = 0;
if (l <= tr[u].l && tr[u].r <= r)
sum += tr[u].sum;
else
{
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) sum += query(u << 1, l, r);
if (mid + 1 <= r) sum += query(u << 1 | 1, l, r);
}
return sum;
}
int main()
{
scanf("%lld%lld", &n, &m);
for (LL i = 1; i <= n; i ++ )
scanf("%lld", &a[i]);
build(1, 1, n);
while (m -- )
{
LL k, a, b;
scanf("%lld%lld%lld", &k, &a, &b);
if (!k)
printf("%lld\n", query(1, a, b));
else
modify(1, a, b);
}
return 0;
}