## 代码
```cpp
#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=j;i<=k;i++)
const int N = 2010;
struct XX {
int x, Ly, Lz, Ry, Rz, v;
} a[210];
int n, m = 2001, tot, w, b[N][N << 2], t[N][N << 2];
long long as;
#define mid ((l + r) >> 1)
#define lc (u << 1)
#define rc ((u << 1) | 1)
void Up(int u, int l, int r) {
if (t[w][u]) b[w][u] = r - l + 1;
else if (l != r) b[w][u] = b[w][lc] + b[w][rc];
else b[w][u] = 0;
}
void Upd(int u, int l, int r, int x, int y, int v) {
if (y < l || r < x) return;
if (x <= l && r <= y) return t[w][u] += v, Up(u, l, r);
Upd(lc, l, mid, x, y, v), Upd(rc, mid + 1, r, x, y, v), Up(u, l, r);
}
void Upd(int Lx, int Ly, int Rx, int Ry, int v) {
for (w = Lx; w <= Rx; w++) Upd(1, 1, m, Ly, Ry, v);
}
int main() {
scanf("%d", &n);
rep(i, 1, n) {
int x, y, z, r;
scanf("%d%d%d%d", &x, &y, &z, &r), x += 1001, y += 1001, z += 1001;
a[++tot] = {x - r, y - r + 1, z - r + 1, y + r, z + r, 1};
a[++tot] = {x + r, y - r + 1, z - r + 1, y + r, z + r, -1};
}
sort(a + 1, a + tot + 1, [](XX u, XX v) { return u.x < v.x; });
Upd(a[1].Ly, a[1].Lz, a[1].Ry, a[1].Rz, a[1].v);
rep(i, 2, tot) {
long long s = 0;
rep(j, 1, m) s += b[j][1];
as += 1ll * (a[i].x - a[i - 1].x) * s;
Upd(a[i].Ly, a[i].Lz, a[i].Ry, a[i].Rz, a[i].v);
}
printf("%lld\n", as);
}
```
### 小引申
如果变成一般性的长方体覆盖,怎么做?
把 $x,y,z$ 全部离散化,对每一维做一次扫描线是 $\mathcal O(n^2\log n)$ 的。
更直接的想法是 $\mathcal O(n\log^3n)$:
问题变成需要支持 矩阵加 和 对整个平面查询有多少个数大于 0(要先离散化):
树套树,但是外层线段树每个节点都对应一棵线段树,设外层线段树进行了一次区间加,涉及到了 $\log n$ 个节点;
这些点和他们的所有祖先受到了影响,由于深度 $\log$ 层,收到影响的最多有 $\log^2n$ 个节点;
对所有受到影响的这些点代表的线段树进行 update,$\mathcal O(n\log^3n)$,十分无脑;空间 $\mathcal O(n^2)$。
我尝试对这个方法进行标记永久化,但是没想出来……
或者分块什么的?