关于线段树区间修改&查询
查看原帖
关于线段树区间修改&查询
763398
AchorX楼主2023/8/12 19:59
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
#define int long long
int sum[N << 2], lazy[N << 2], a[N];
int n, m;
void build(int l, int r, int rt){
	if(l == r){
		sum[rt] = a[l];
		return ;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
}
void pushdown(int s, int t, int rt){
	int mid = (s + t) >> 1;
	if(lazy[rt]){
		lazy[rt << 1] += lazy[rt];
		lazy[rt << 1 | 1] += lazy[rt];
		sum[rt << 1] += lazy[rt] * (mid - s + 1);
		sum[rt << 1 | 1] += lazy[rt] * (t - mid);
		lazy[rt] = 0;
	}
//	sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void update(int s, int t, int l, int r, int w, int rt){
	if(l <= s && t <= r){
		sum[rt] += (t - s + 1) * w;
		lazy[rt] += w;
		return ;
	}
	int mid = (s + t) >> 1;
	if(l <= mid) update(s, mid, l, r,  w, rt << 1);
	if(r > mid) update(mid + 1, t, l, r, w, rt << 1 | 1);
	sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
int ask(int s, int t, int l, int r, int rt){
	if(l <= s && t <= r) return sum[rt];
	pushdown(s, t, rt);
	int mid = (s + t) >> 1;
	int ans = 0;
	if(l <= mid) ans += ask(s, mid, l, r, rt << 1);
	if(mid < r) ans += ask(mid + 1, t, l, r, rt << 1 | 1);
	return ans;
}
void read() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
	build(1, n, 1);
	for (int i = 1; i <= m; ++i) {
		int id;
		scanf("%lld", &id);
		if(id == 1){
			int l, r, w;
			scanf("%lld%lld%lld", &l, &r, &w);
			update(1, n, l, r, w, 1);
		}else{
			int l, r;
			scanf("%lld%lld", &l, &r);
			printf("%lld\n", ask(1, n, l, r, 1));
		}
	}
}
signed main() {
	read();
	return 0;
}

rt, 求查错

2023/8/12 19:59
加载中...