求相交三次及以上的立方体体积。
代码参考的kuangbin的博客,
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2005;
struct node{
int l,r;
ll lf,rf; //实际的左右端点。
int c; //覆盖次数。
ll once,twice,more;
}tree[maxn<<2];
ll x[maxn];
ll z[maxn];
struct Node{
ll y;
ll x1,x2;
ll z1,z2;
ll f;
}line[maxn],tmp[maxn];
bool cmp(Node a,Node b){
return a.y<b.y;
}
void build(int i,int l,int r){
tree[i].l=l;
tree[i].r=r;
tree[i].lf=x[l];
tree[i].rf=x[r];
tree[i].c=0;
tree[i].once=tree[i].twice=tree[i].more=0;
if(r==l+1) return;
int mid=l+r>>1;
build(i<<1,l,mid);
build(i<<1|1,mid,r);
}
void push_up(int i){
if(tree[i].c>2){
tree[i].more=tree[i].rf-tree[i].lf;
tree[i].once=tree[i].twice=0; //这块很重要。
}else if(tree[i].c==2){
if(tree[i].l+1==tree[i].r){ //叶子节点
tree[i].more=0;
tree[i].twice=tree[i].rf-tree[i].lf;
tree[i].once=0;
return;
}
tree[i].more=tree[i<<1].once+tree[i<<1].twice+tree[i<<1].more+
tree[i<<1|1].once+tree[i<<1|1].twice+tree[i<<1|1].more;
tree[i].twice=tree[i].rf-tree[i].lf-tree[i].more;
tree[i].once=0;
return;
}else if(tree[i].c==1){
if(tree[i].l+1==tree[i].r){
tree[i].more=tree[i].twice=0;
tree[i].once=tree[i].rf-tree[i].lf;
return;
}
tree[i].more=tree[i<<1].twice+tree[i<<1].more+
tree[i<<1|1].twice+tree[i<<1|1].more;
tree[i].twice=tree[i<<1].once+tree[i<<1|1].once;
tree[i].once=tree[i].rf-tree[i].lf-tree[i].more-tree[i].twice;
}else{
if(tree[i].l+1==tree[i].r){
tree[i].more=tree[i].once=tree[i].twice=0;
return;
}
tree[i].more=tree[i<<1].more+tree[i<<1|1].more;
tree[i].twice=tree[i<<1].twice+tree[i<<1|1].twice;
tree[i].once=tree[i<<1].once+tree[i<<1|1].once;
}
}
void update(int i,Node e){
if(tree[i].lf>=e.x1&&tree[i].rf<=e.x2){
tree[i].c+=e.f;
push_up(i);
return;
}
if(e.x2<=tree[i<<1].rf) update(i<<1,e);
else if(e.x1>=tree[i<<1|1].lf) update(i<<1|1,e);
else{
Node temp=e;
temp.x2=tree[i<<1].rf;
update(i<<1,temp);
temp=e;
temp.x1=tree[i<<1|1].lf;
update(i<<1|1,temp);
}
push_up(i);
}
int main(){
int T;
scanf("%d",&T);
for(int cs=1;cs<=T;cs++){
ll x1,x2,y1,y2,z1,z2;
int n;
scanf("%d",&n);
int t=1;
for(int i=0;i<n;i++){
scanf("%lld%lld%lld%lld%lld%lld",&x1,&y1,&z1,&x2,&y2,&z2);
line[t].y=y1;
line[t].x1=x1;
line[t].x2=x2;
line[t].z1=z1;
line[t].z2=z2;
line[t].f=1;
x[t]=x1;
z[t++]=z1;
line[t].y=y2;
line[t].x1=x1;
line[t].x2=x2;
line[t].z1=z1;
line[t].z2=z2;
line[t].f=-1;
x[t]=x2;
z[t++]=z2;
}
sort(line+1,line+t,cmp);
sort(x+1,x+t);
int t1=unique(x+1,x+t)-x;
build(1,1,t1-1);
sort(z+1,z+t);
int t2=unique(z+1,z+t)-z;
ll ans=0,area=0;
for(int i=1;i<t2-1;i++){
int m=1;
for(int j=1;j<t;j++){
if(line[j].z1<=z[i]&&line[j].z2>z[i]){
tmp[m++]=line[j];
}
}
area=0;
update(1,tmp[1]);
for(int j=2;j<m;j++){
area+=tree[1].more*(tmp[j].y-tmp[j-1].y);
update(1,tmp[j]);
}
ans+=area*(z[i+1]-z[i]);
}
printf("Case %d: %lld\n",cs,ans);
}
return 0;
}