模板写炸求调
查看原帖
模板写炸求调
224593
Grim_Souls楼主2021/4/9 22:48
#include<stdio.h>
#include<iostream>
#define LL long long
const int N = 1e5;
using namespace std;

int n, m;LL s[N << 2], p[N << 2], a[N << 2];

void build(int k, int l, int r) {
	if (l == r) {
		s[k] = a[l];
		return;
	}
	int mid = l + r >> 1;
	build(k << 1, l, mid);
	build(k << 1 | 1, mid + 1, r);
	s[k] = s[k << 1] + s[k << 1 | 1];
}

void update(int k, int l, int r, int x, int y, LL u) {
	if (r < x || l > y)
		return;
	if (x <= l && r <= y) {
		s[k] = s[k] + u * (r - l + 1);
		p[k] = p[k] + u;
		return;
	}
	int mid = l + r >> 1;
	if (p[k] && x != y) {
		p[k << 1] += p[k]; p[k << 1 | 1] += p[k];
		s[k << 1] += (m - l + 1) * p[k]; s[k << 1 | 1] += (r - m) * p[k];
		p[k] = 0;
	}
	update(k << 1, l, mid, x, y, u);
	update(k << 1 | 1, mid + 1, r, x, y, u);
	s[k] = s[k << 1] + s[k << 1 | 1];
}

LL query(int k, int l, int r, int x, int y) {
	if (x > r || y < l)
		return 0;
	int mid = l + r >> 1;
	if (x <= l && r <= y)
		return s[k];
	int m = l + r >> 1;
	if (p[k] && x != y) {
		p[k << 1] += p[k]; p[k << 1 | 1] += p[k];
		s[k << 1] += (m - l + 1) * p[k]; s[k << 1 | 1] += (r - m) * p[k];
		p[k] = 0;
	}
	return query(k << 1, l, m, x, y) + query(k << 1 | 1, m + 1, r, x, y);
}


int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i)
		scanf("%lld", a + i);
	build(1, 1, n);
	while(m--) {
		int q, x, y; LL k;
		scanf("%d%d%d", &q, &x, &y);
		if (q == 1) {
			scanf("%lld", &k);
			update(1, 1, n, x, y, k);
		}
		else printf("%lld\n", query(1, 1, n, x, y));
	}
	return 0;
}
2021/4/9 22:48
加载中...