CF390E Inna and Large Sweet Matrix

CF390E Inna and Large Sweet Matrix

求 \(D - I\),用图像考虑的话,即为这样一个表格(求每个格对应矩阵和乘以格内标的数):

\([1, y1)\) \([y1, y2]\) \((y2, m]\)
\([1, x1)\) -1 0 -1
\([x1, x2]\) 0 1 0
\((x2, n]\) -1 0 -1

加上矩阵总和之后:

\([1, y1)\) \([y1, y2]\) \((y2, m]\)
\([1, x1)\) 0 1 0
\([x1, x2]\) 1 2 1
\((x2, n]\) 0 1 0

则计算答案的公式为:

\[D - I = \text{行区间和}([x_1, x_2]) + \text{列区间和}([y_1, y_2]) - total \]

其中:

  • 行区间和 \([x_1, x_2]\):第 \(x_1\) 到 \(x_2\) 行的每行糖果总数之和;
  • 列区间和 \([y_1, y_2]\):第 \(y_1\) 到 \(y_2\) 列的每列糖果总数之和;
  • \(total\):整个矩阵的糖果总数。

那么我们可以分别维护两个线段树:

  1. 每行的糖果总数(记为线段树 \(x\));
  2. 每列的糖果总数(记为线段树 \(y\))。

每次区间加操作时:

  • 线段树 \(x\):对 \([x_1, x_2]\) 行,每行增加 \(v \times (y_2 - y_1 + 1)\) 颗糖果;
  • 线段树 \(y\):对 \([y_1, y_2]\) 列,每列增加 \(v \times (x_2 - x_1 + 1)\) 颗糖果;
  • 同时维护全局总数 \(total\)。
#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int MAXN = 4e6 + 9;
struct SEG {
	struct Node {
		int val, lazy;
		Node() : val(0), lazy(0) {}
	}t[MAXN << 2];
	void push_down(int p, int l, int r) {
		if(!t[p].lazy) return;
		int mid = (l + r) >> 1;
		t[p << 1].val += (mid - l + 1) * t[p].lazy;
		t[p << 1].lazy += t[p].lazy;
		t[(p << 1) + 1].val += (r - mid) * t[p].lazy;
		t[(p << 1) + 1].lazy += t[p].lazy;
		t[p].lazy = 0;
	}
	void push_up(int p) {
		t[p].val = t[p << 1].val + t[(p << 1) + 1].val;
	}
	void update(int p, int l, int r, int nl, int nr, int v) {
		if(nl <= l && r <= nr) {
			t[p].val += (r - l + 1) * v;
			t[p].lazy += v;
			return;
		}
		push_down(p, l, r);
		int mid = (l + r) >> 1;
		if(nl <= mid) update(p << 1, l, mid, nl, nr, v);
		if(nr > mid) update((p << 1) + 1, mid + 1, r, nl, nr, v);
		push_up(p);
	}
	int query(int p, int l, int r, int nl, int nr) {
		if(nl <= l && r <= nr) return t[p].val;
		push_down(p, l, r);
		int mid = (l + r) >> 1, rt = 0;
		if(nl <= mid) rt += query(p << 1, l, mid, nl, nr);
		if(nr > mid) rt += query((p << 1) + 1, mid + 1, r, nl, nr);
		return rt;
	}
	void update(int n, int l, int r, int v) {update(1, 1, n, l, r, v);}
	int query(int n, int l, int r) {return query(1, 1, n, l, r);}
}x, y;
int n, m, w, op, xx1, yy1, xx2, yy2, v, sum;
signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m >> w;
	while(w--) {
		cin >> op >> xx1 >> yy1 >> xx2 >> yy2;
		if(!op) {
			cin >> v;
			x.update(n, xx1, xx2, (yy2 - yy1 + 1) * v);
			y.update(m, yy1, yy2, (xx2 - xx1 + 1) * v);
			sum += (xx2 - xx1 + 1) * (yy2 - yy1 + 1) * v;
		}
		else {
			int ans = x.query(n, xx1, xx2) + y.query(m, yy1, yy2);
			ans -= sum;
			cout << ans << '\n';
		}
	}
	return 0;
}
posted @ 2026-09-29 21:19  qiuyu07215  阅读(0)  评论(0)    收藏  举报