rainygame @ 2023-03-23 15:00:47
RT。没有一个对的:
#include <bits/stdc++.h>
using namespace std;
#define MAXN 500001
int n, m, x, y, opt;
long long k;
long long a[MAXN];
struct Tree{ // 线段树结点
int l, r, lzt; // lzt表示lazytag,懒标记
long long sum;
}tree[MAXN<<2]; // 注意要开到4倍空间
void build(int l, int r, int p){ // 建线段树
tree[p].l = l; // 定义左边界
tree[p].r = r; // 定义右边界
if (l == r){ // 如果[l,r]为一个单点
tree[p].sum = a[l]; // 则它的权值为那个单点的数
return;
}
int mid = (l+r)>>1;
build(l, mid, p<<1); // 递归查找左儿子
build(mid+1, r, (p<<1)+1); // 递归查找右儿子
tree[p].sum = tree[p<<1].sum + tree[(p<<1)+1].sum; // 即为两儿子之和
}
void push_down(int p){
if (tree[p].lzt){
tree[p<<1].lzt += tree[p].lzt; //左右儿子分别加上父亲的lz
tree[(p<<1)+1].lzt += tree[p].lzt;
int mid = (tree[p].l + tree[p].r) >> 1;
tree[p<<1].sum += tree[p].lzt * (mid-tree[p<<1].l+1); //左右分别求和加起来
tree[(p<<1)+1].sum += tree[p].lzt * (tree[(p<<1)+1].r-mid);
tree[p].lzt = 0; //父亲lazytag归零
}
}
void add(int l, int r, long long k, int p){ // [l,r]加上k,现在搜到了p
if (tree[p].l >= l && tree[p].r <= r){ // 完全在区间内
tree[p].sum += k;
tree[p].lzt += k; // 记录lazytag
return;
}
push_down(p);
if (tree[p<<1].r >= l) add(l, r, k, p<<1); // 递归左儿子
if (tree[(p<<1)+1].l <= r) add(l, r, k, (p<<1)+1); // 递归右儿子
tree[p].sum = tree[p<<1].sum + tree[(p<<1)+1].sum; // 加和
}
long long query(int l, int r, int p){ // 查询区间[l,r]的和
if (tree[p].l >= l && tree[p].r <= r) return tree[p].sum;
push_down(p);
long long ans = 0;
if (tree[p].l == tree[p].r) return ans; // 单点
if (tree[p<<1].r >= l) ans += query(l, r, p<<1); // 递归左儿子
if (tree[(p<<1)+1].l <= r) ans += query(l, r, (p<<1)+1); // 递归右儿子
return ans; // 返回
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i=1; i<=n; i++) cin >> a[i];
build(1, n, 1);
while (m--){
cin >> opt;
if (opt == 1){ // 区间修改
cin >> x >> y >> k;
add(x, y, k, 1);
}else{ // 区间查询
cin >> x >> y;
cout << query(x, y, 1) << '\n';
}
}
return 0;
}
是学着 这个 来写的。
by yllcm @ 2023-03-23 15:24:42
@rainygame add 没乘区间长度
by rainygame @ 2023-03-23 15:28:17
@yllcm 已A,谢谢