社区讨论
样例没过 & 0 pts 求调
P3372【模板】线段树 1参与者 3已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @mhju1unj
- 此快照首次捕获于
- 2025/11/04 08:30 4 个月前
- 此快照最后确认于
- 2025/11/04 08:30 4 个月前
CPP
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int n, m;
ll a[N], ans[N << 2], tag[N << 2];
int ls(int x){return x << 1;}
int rs(int x){return x << 1 | 1;}
void push_up(int p)
{
ans[p] = ans[ls(p)] + ans[rs(p)];
return;
}
void build(int l, int r, int p)
{
tag[p] = 0;
if (l == r)
{
ans[p] = a[l];
return;
}
int mid = (l + r) >> 1;
build(l, mid, ls(p));
build(mid + 1, r, rs(p));
push_up(p);
return;
}
void calc(int l, int r, int p, ll k)
{
tag[p] += k;
ans[p] += k * (r - l + 1);
return;
}
void push_down(int l, int r, int p)
{
int mid = (l + r) >> 1;
calc(l, mid, ls(p), tag[p]);
calc(mid + 1, r, rs(p), tag[p]);
tag[p] = 0;
return;
}
void update(int l, int r, int p, ll k, int nl, int nr)
{
if (l >= nl && r <= nr)
{
ans[p] += k * (r - l + 1);
tag[p] += k;
return;
}
push_down(l, r, p);
int mid = (l + r) >> 1;
if (nl <= mid)
update(l, mid, ls(p), k, nl, nr);
if (nr > mid)
update(mid + 1, r, rs(p), k, nl, nr);
push_up(k);
return;
}
ll query(int l, int r, int p, int nl, int nr)
{
int res = 0;
if (l >= nl && r <= nr)
return ans[p];
int mid = (l + r) >> 1;
if (nl <= mid)
res += query(l, mid, ls(p), nl, nr);
if (nr > mid)
res += query(mid + 1, r, rs(p), nl, nr);
return res;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i)
scanf("%lld", a + i);
build(1, n, 1);
while (m--)
{
int op;
int l, r;
ll k;
scanf("%d", &op);
if (op == 1)
{
scanf("%d%d%lld", &l, &r, &k);
update(1, n, 1, k, l, r);
}
else
{
scanf("%d%d", &l, &r);
printf("%lld\n", query(1, n, 1, l, r));
}
}
return 0;
}
回复
共 7 条回复,欢迎继续交流。
正在加载回复...