题意:
。。。就是求体积交。。。
解析:
把每一层z抽出来,计算面积交, 然后加起来即可。。!
去看一下 二维面积交的代码 再看看这个三维面积交的代码。。 down函数里 你发现了什么规律!!!
参考二维面积交:https://www.cnblogs.com/WTSRUVF/p/9274318.html
代码如下
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #define mem(a, b) memset(a, b, sizeof(a)) using namespace std; const int maxn = 8010, INF = 0x7fffffff; typedef long long LL; int X[maxn]; struct node{ int l, r, w; int lx, rx, sum, lsum, llsum; }Node[maxn]; struct edge{ int lxx, rxx, y, z1, z2; int f; }Edge[maxn*2]; int cmp(edge a, edge b) { return a.y < b.y; } void build(int k, int ll, int rr) { Node[k].l = ll, Node[k].r = rr; Node[k].w = Node[k].sum = Node[k].lsum = Node[k].llsum = 0; Node[k].lx = X[ll]; Node[k].rx = X[rr]; if(ll + 1 == rr) return; int m = (ll + rr) / 2; build(k*2, ll, m); build(k*2+1, m, rr); } void down(int k) { int len = Node[k].rx - Node[k].lx; if(Node[k].w >= 3) { Node[k].sum = Node[k].lsum = Node[k].llsum = len; } else if(Node[k].w == 2) { Node[k].lsum = Node[k].llsum = len; if(Node[k].l + 1 == Node[k].r) Node[k].sum = 0; else Node[k].sum = Node[k*2].lsum + Node[k*2+1].lsum; } else if(Node[k].w == 1) { Node[k].lsum = len; if(Node[k].l + 1 == Node[k].r) Node[k].llsum = Node[k].sum = 0; else { Node[k].llsum = Node[k*2].lsum + Node[k*2+1].lsum; Node[k].sum = Node[k*2].llsum + Node[k*2+1].llsum; } } else { if(Node[k].l + 1 == Node[k].r) Node[k].sum = Node[k].lsum = Node[k].llsum = 0; else { Node[k].lsum = Node[k*2].lsum + Node[k*2+1].lsum; Node[k].llsum = Node[k*2].llsum + Node[k*2+1].llsum; Node[k].sum = Node[k*2].sum + Node[k*2+1].sum; } } } void update(int k, edge e) { if(Node[k].lx == e.lxx && Node[k].rx == e.rxx) { Node[k].w += e.f; down(k); return; } if(e.rxx <= Node[k*2].rx) update(k*2, e); else if(e.lxx >= Node[k*2+1].lx) update(k*2+1, e); else { edge temp = e; temp.rxx = Node[k*2].rx; update(k*2, temp); temp = e; temp.lxx = Node[k*2+1].lx; update(k*2+1, temp); } down(k); } int main() { int T, kase = 0; scanf("%d",&T); while(T--) { int n, cnt = 0; scanf("%d",&n); for(int i=0; i<n; i++) { int x1, y1, z1, x2, y2, z2; scanf("%d%d%d%d%d%d", &x1, &y1, &z1, &x2, &y2, &z2); Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y1, Edge[cnt].f = 1, Edge[cnt].z1= z1, Edge[cnt].z2 = z2; X[cnt] = x1; Edge[++cnt].lxx = x1, Edge[cnt].rxx = x2, Edge[cnt].y = y2, Edge[cnt].f = -1, Edge[cnt].z1= z1, Edge[cnt].z2 = z2; X[cnt] = x2; } sort(Edge+1, Edge+cnt+1, cmp); sort(X+1, X+cnt+1); int m = unique(X+1, X+cnt+1) - (X+1); LL ret = 0; for(int i=-500; i<=500; i++) { build(1, 1, m); int ans = 0; edge line[maxn]; for(int j=1; j<=cnt; j++) { if(Edge[j].z1 <= i && Edge[j].z2 > i) line[++ans] = Edge[j]; } for(int j=1; j<ans; j++) { update(1, line[j]); ret += (LL)Node[1].sum * (line[j+1].y - line[j].y); } } printf("Case %d: %lld ",++kase,ret); } return 0; }