分块,零分蒟蒻求助
  • 板块P2357 守墓人
  • 楼主DiDi123
  • 当前回复3
  • 已保存回复3
  • 发布时间2021/3/17 15:47
  • 上次更新2023/11/5 01:58:00
查看原帖
分块,零分蒟蒻求助
280604
DiDi123楼主2021/3/17 15:47
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 200001;
long long group, n, f;
long long a1, a2, a3, a4, h, cnt = 1;
long long a[N], add[N], sum[N], pu[N],pos[N];
void Addl(long long l, long long r, long long k) {
	long long start = (pos[l]-1) * group +1, end = pos[l] * group;
	for (long long i = pos[l]; i <= pos[r]; i++) {
		if (l <= start && r >= end) {
			add[i] += k;
			sum[i] += group * k;
			start += group;
			end += group;
			continue;
		}
 if (l > start && r < end) {
			for (long long j = l; j <= r; j++)
				a[j] += k;
			sum[i] += (l - r + 1) * k;
			return;
		} else {
			if (l > start) {
				for (long long j = l; j <= end; j++)
					a[j] += k;
				sum[i] += (end - l + 1) * k;
			}
			else if (r < end) {
				for (long long j = start; j <= r; j++)
					a[j] += k;
				sum[i] += (r - start + 1) * k;
			}
		}
		start += group;
		end += group;
	}
}
long long quary(long long l, long long r) {
	long long start = (pos[l] - 1) * group +1, end = pos[l] * group;
	long long ANS = 0;
	for (long long i = pos[l]; i <= pos[r]; i++) {
		if (l <= start && r >= end) {
			ANS += sum[i];
			start += group;
			end += group;
			continue;
		}
		for (long long j = start; j <= end; j++)
			a[j] += add[i];
		add[i] = 0;
		if (l > start && r < end) {
			for (long long j = l; j <= r; j++)
				ANS += a[j];
			return ANS;
		} else {
			if (l > start) {
				for (long long j = l; j <= end; j++)
					ANS += a[j];
			}
			if (r < end) {
				for (long long j = start; j <= r; j++)
					ANS += a[j];
			}
		}
		start += group;
		end += group;
	}
	return ANS;
}
int main() {
	cin >> n >> f;
	group = sqrt(n);
	memset(a, 0, sizeof(a));
	memset(add, 0, sizeof(add));
	memset(sum, 0, sizeof(sum));
	for (long long i = 1; i <= n; i++)
	{
		cin >> a[i];
		h = (i - 1) / group + 1;
		pos[i] = h;
		sum[h] += a[i];
	}
	for (long long i = 1; i <= f; i++) {
		cin >> a1;
		if (a1 == 1) {
			cin >> a2 >> a3 >> a4;
			Addl(a2, a3, a4);
		} else if (a1 == 2) {
			cin >> a2;
			a[1] += a2;
			sum[1] += a2; ;
		} else if (a1 == 3) {
			cin >> a2;
			a[1] -= a2;
			sum[1] -= a2;
		} else if (a1 == 4) {
			cin >> a2 >> a3;
			pu[cnt++] = quary(a2, a3);
		} else if (a1 == 5) {
			pu[cnt++] = a[1] + add[1];
		}
	}
	for (long long i = 1; i < cnt; i++)
		cout << pu[i] << endl;

}

2021/3/17 15:47
加载中...