分块模板爆零求助
  • 板块灌水区
  • 楼主mediocre_
  • 当前回复8
  • 已保存回复8
  • 发布时间2024/10/13 20:37
  • 上次更新2024/10/14 08:19:04
查看原帖
分块模板爆零求助
565707
mediocre_楼主2024/10/13 20:37

题目是 模板线段树1

按照老师的思路写的

感觉没问题

样例可以过

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100010;
long long a[MAXN], sum[MAXN], add[MAXN];
int L[MAXN], R[MAXN], pos[MAXN], n, m, t;
void change(int l, int r, long long d) {
	int p = pos[l], q = pos[r];
	if (p == q) { // 在同一个区间内
		for (int i = l; i <= r; ++i) a[i] += d;
		sum[p] = d * (r - l + 1); // 高斯求和
	}
	else { // 不在同一个区间
		for (int i = p + 1; i <= q - 1; ++i) add[i] += d;
		for (int i = l; i <= R[p]; ++i) a[i] += d;
		sum[p] += (R[p] - l + 1) * d;
		for (int i = L[q]; i <= r; ++i) a[i] += d;
		sum[p] += (r - L[q] + 1) * d;
	}
}
long long ask(int l, int r) {
	int p = pos[l], q = pos[r];
	long long ans = 0;
	if (p == q) {
		for (int i = l; i <= r; ++i) ans += a[i];
		ans += add[p] * (r - l + 1);
	}
	else {
		for (int i = p + 1; i <= q - 1; ++i) ans += sum[i] + add[i] * (R[i] - L[i] + 1);
		for (int i = l; i <= R[p]; ++i) ans += a[i];
		ans += (R[p] - l + 1) * add[p];
		for (int i = L[q]; i <= r; ++i) ans += a[i];
		ans += (r - L[q] + 1) * add[q];
	}
	return ans;
}
int main() {
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
    t = sqrt(n);
    for (int i = 1; i <= t; ++i) {
		L[i] = (i - 1) * sqrt(n) + 1;
		R[i] = i * sqrt(n);
	}
	if (R[t] < n) ++t, L[t] = R[t - 1] + 1, R[t] = n;
	for (int i = 1; i <= n; ++i)
		for (int j = L[i]; j <= R[i]; ++j)
			pos[j] = i, sum[i] += a[j];
	while (m--) {
		int opt, x, y; 
		long long k;
		scanf("%d%d%d", &opt, &x, &y);
		if (opt == 1) {
			scanf("%lld", &k);
			change(x, y, k);
		}
		else printf("%lld\n", ask(x, y));
	}
    return 0;
}
2024/10/13 20:37
加载中...