题目连接
#题意
题目大意 原数组a有n个数字q次操作
1查询[l, r]的和s 要求s = ∑a[i] * (r - i + 1)
2修改b位置的值为c
使用线段树维护两个值s和w s = ∑a[i] w = ∑a[i] * (n - i + 1)
查询时 w - s * (n - r)即为答案 注意爆int
#AC代码
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;
int a[MAXN], n, q;
struct node
{
int l, r;
ll s, w;
}tree[MAXN << 2];
inline void PushUp(int x)
{
tree[x].s = tree[x << 1].s + tree[x << 1 | 1].s;
tree[x].w = tree[x << 1].w + tree[x << 1 | 1].w;
}
void Build(int x, int l, int r)
{
tree[x].l = l, tree[x].r = r, tree[x].s = tree[x].w = 0;
if (l == r)
tree[x].s = a[l], tree[x].w = 1LL * a[l] * (n - l + 1); //爆int
else
{
int m = l + r >> 1;
Build(x << 1, l, m);
Build(x << 1 | 1, m + 1, r);
PushUp(x);
}
}
void Update(int x, int l, int r, ll v)
{
int xl = tree[x].l, xr = tree[x].r;
if (xl == xr)
tree[x].s = v, tree[x].w = v * (n - xl + 1);
else
{
int xm = xl + xr >> 1;
if (xm >= l)
Update(x << 1, l, r, v);
else
Update(x << 1 | 1, l, r, v);
PushUp(x);
}
}
void Query(int x, int l, int r, ll &s, ll &w)
{
int xl = tree[x].l, xr = tree[x].r;
if (l <= xl && r >= xr)
s += tree[x].s, w += tree[x].w;
else
{
int xm = xl + xr >> 1;
if (xm >= l)
Query(x << 1, l, r, s, w);
if (xm < r)
Query(x << 1 | 1, l, r, s, w);
}
}
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
cin >> n >> q;
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
Build(1, 1, n);
for (int i = 0; i < q; i++)
{
ll s = 0, w = 0;
int op, l, r;
scanf("%d%d%d", &op, &l, &r);
if (op == 1)
{
Query(1, l, r, s, w);
printf("%lld\n", w - s * (n - r)); //公式
}
else
Update(1, l, l, r);
}
return 0;
}