社区讨论
动态开点线段树样例不对求助
P3372【模板】线段树 1参与者 5已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @lqwho6v1
- 此快照首次捕获于
- 2024/01/02 23:13 2 年前
- 此快照最后确认于
- 2024/01/03 14:49 2 年前
CPP
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define sum(x) tr[x].sum
#define ls(x) (tr[x].lc)
#define rs(x) (tr[x].rc)
#define lazy(x) (tr[x].lazy)
const int N = 1e5+5;
struct node{
int lc, rc;
ll sum, lazy;
}tr[N << 3];
int cnt = 1;
int n, q;
ll x;
void pushup(int k){
sum(k) = sum(ls(k)) + sum(rs(k));
}
void pushdown(int k, int l, int r){
if (lazy(k)){
if (!ls(k)) ls(k) = ++cnt;
if (!rs(k)) rs(k) = ++cnt;
lazy(ls(k)) += lazy(k);
lazy(rs(k)) += lazy(k);
int mid = (l + r) >> 1;
sum(ls(k)) += (mid - l + 1) * lazy(k);
sum(rs(k)) += (r - mid) * lazy(k);
lazy(k) = 0;
}
}
void build(int &k, int l, int r, int v, int x){
if (!k) k = ++cnt;
if (l == r){
sum(k) = x;
}
else{
int mid = (l + r) >> 1;
if (v <= mid) build(ls(k), l, mid, v, x);
else build(rs(k), mid + 1, r, v, x);
pushup(k);
}
}
void add(int &k, int l, int r, int L, int R, int x){
if (!k) k = ++cnt;
if (L <= l && R >= r){
lazy(k) += x;
sum(k) += (r - l + 1) * x;
}
else{
pushdown(k, l, r);
int mid = (l + r) >> 1;
if (L <= mid) add(ls(k), l, mid, L, R, x);
if (R > mid) add(rs(k), mid + 1, r, L, R, x);
pushup(k);
}
}
ll query(int k, int l, int r, int L, int R){
if (!k) return 0;
if (L <= l && R >= r) return sum(k);
pushdown(k, l, r);
int mid = (l + r) >> 1;
ll res = 0;
if (L <= mid) res += query(ls(k), l, mid, L, R);
if (R > mid) res += query(rs(k), mid + 1, r, L, R);
return res;
}
int main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> q;
for (int i = 1;i <= n;i++){
cin >> x;
int tmp = 1;
build(tmp, 1, n, i, x);
}
while (q--){
int op;
cin >> op;
if (op == 1){
int L, R, x;
cin >> L >> R >> x;
int tmp = 1;
add(tmp, 1, n, L, R, x);
}
else{
int L, R;
cin >> L >> R;
cout << query(1, 1, n, L, R) << '\n';
}
}
return 0;
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...