求助线段树Re
查看原帖
求助线段树Re
804757
Light_Star_RPmax_AFO楼主2023/8/23 16:59

线段树模板1

#include <bits/stdc++.h>
#define ll long long
using namespace std;

inline ll read(){
	int f = 1;
	ll x = 0;
	char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-')f = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
inline void print(int x){
	if(x > 9)print(x / 10);
	putchar(x % 10 + '0');
}

ll n, q, d[270010], b[270010], a[100010];

void build(ll l, ll r, ll p){
	if(l == r){
		d[p] = a[l];
		return ;
	}
	ll mid = l + ((r - l) >> 1);
	build(l, mid, (p << 1)), build(mid + 1, r, ((p << 1)) | 1);
	d[p] = d[(p << 1)] + d[((p << 1)) | 1];
}

ll getsum(ll l, ll r, ll s, ll t, ll p){
	if(l <= s && t <= r)
		return d[p];
	ll mid = s + ((t - s) >> 1), sum = 0ll;
	if(b[p])
		d[(p << 1)] += b[p] * (mid - s + 1), d[((p << 1)) | 1] + b[p] * (t - mid), b[(p << 1)] += b[p], b[((p << 1)) | 1] += b[p];
	b[p] = 0;
	if(l <= mid)sum += getsum(l, r, s, mid, (p << 1));
	if(r > mid)sum += getsum(l, r, mid + 1, t, ((p << 1)) | 1);
	return sum;
}

void update(ll l, ll r, ll c, ll s, ll t, ll p){
	if(l <= s && t <= r){
		d[p] += (t - s + 1) * c, b[p] += c;
		return ;
	}
	ll mid = s + ((t - s) >> 1);
	if(b[p]){
		d[(p << 1)] += b[p] * (mid - s + 1), d[(p << 1) | 1] += b[p] * (t - mid);
		b[(p << 1)] += b[p], b[(p << 1) | 1] += b[p];
	}
	b[p] = 0; 
	if(l <= mid)update(l, r, c, s, mid, (p << 1));
	if(r > mid)update(l, r, c, s, mid + 1, ((p << 1)) | 1);
	d[p] = d[(p << 1)] + d[((p << 1)) | 1]; 
}

signed main(){
	n = read(), q = read();
	for(ll i = 1;i <= n;i++)
		a[i] = read();
	build(1, n, 1);
	while(q--){
		ll op = read();
		if(op == 1){
			ll x = read(), y = read(), k = read();
			update(x, y, k, 1, n, 1);
		}else{
			ll x = read(), y = read();
			cout << getsum(x, y, 1, n, 1) << endl;
		}
	} 
	return 0;
}
2023/8/23 16:59
加载中...