Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1036 Accepted Submission(s): 318
//求矩形交3次以上部分体积
//枚举Z轴然后线段树算面积
//搞了一下午、加深了对求面积题目的理解呀
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <stack>
#define N 2003
#define lson l,m,k<<1
#define rson m,r,k<<1|1
using namespace std;
struct node
{
int x,y1,y2,z1,z2;
int flag;
bool operator<(const node&a)const
{
return x<a.x;
}
};
struct tree
{
int cover,one,two,more;//代表的是当前区间被覆盖1,2,2次以上线段长度
};
int rcy[N],rcz[N];
node In[N];
tree st[N<<2];
void build(int l,int r,int k)
{
st[k].cover=st[k].one=st[k].two=st[k].more=0;
if(l+1==r)
return;
int m=(l+r)>>1;
build(lson);
build(rson);
}
void up(int &k,int &l,int &r)//这个是这类题目的关键
{
int ls=k<<1,rs=k<<1|1;
if(st[k].cover>2)
{
st[k].more=rcy[r]-rcy[l];
st[k].one=st[k].two=0;
return;
}
if(st[k].cover==2)
{
if(l+1==r){st[k].two=rcy[r]-rcy[l];st[k].one=st[k].more=0;return ;}
st[k].more=st[ls].one+st[rs].one+st[ls].two+st[rs].two;
st[k].more+=st[ls].more+st[rs].more;
st[k].two=rcy[r]-rcy[l]-st[k].more;
st[k].one=0;
return ;
}
if(st[k].cover==1)
{
if(l+1==r){st[k].one=rcy[r]-rcy[l];st[k].two=st[k].more=0;return ;}
st[k].two=st[ls].one+st[rs].one;
st[k].more=st[ls].two+st[rs].two+st[ls].more+st[rs].more;
st[k].one=rcy[r]-rcy[l]-st[k].more-st[k].two;
return ;
}
if(l+1==r){ st[k].one=st[k].two=st[k].more=0;return;}
st[k].one=st[ls].one+st[rs].one;
st[k].two=st[ls].two+st[rs].two;
st[k].more=st[ls].more+st[rs].more;
}
int flag;
void update(int &y1,int &y2,int l,int r,int k)
{
if(y1<=rcy[l]&&y2>=rcy[r])
{
st[k].cover+=flag;
up(k,l,r);
return;
}
int m=(l+r)>>1;
if(y1<rcy[m]) update(y1,y2,lson);
if(y2>rcy[m]) update(y1,y2,rson);
up(k,l,r);
}
int main()
{
int x1,y1,z1,x2,y2,z2;
int n,t=1,T;
int i,j,k,l,ry,rz;
double v,s;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(j=i=0;i<n;i++)
{
scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
In[j].x=x1;In[j].y1=y1;In[j].y2=y2;
In[j].z1=z1;In[j].z2=z2;
rcy[j]=y1;rcz[j]=z1; In[j++].flag=1;
In[j].x=x2;In[j].y1=y1;In[j].y2=y2;
In[j].z1=z1;In[j].z2=z2;
rcy[j]=y2;rcz[j]=z2; In[j++].flag=-1;
}
sort(In,In+j);
sort(rcy,rcy+j);
sort(rcz,rcz+j);
for(ry=0,i=1;i<j;i++)
if(rcy[i]!=rcy[ry])
rcy[++ry]=rcy[i];
for(rz=0,i=1;i<j;i++)
if(rcz[i]!=rcz[rz])
rcz[++rz]=rcz[i];
v=0;j--;
for(i=0;i<rz;i++)
{
build(0,ry,1);
s=0;
for(k=0;k<j;k++)
{
if(In[k].z1<=rcz[i]&&In[k].z2>rcz[i])
{
flag=In[k].flag;
update(In[k].y1,In[k].y2,0,ry,1);
for(l=k+1;l<j+1;l++)//开始没发现这个问题,Wa的我好郁闷
if(In[l].z1<=rcz[i]&&In[l].z2>rcz[i])
break;
s+=1.0*st[1].more*(In[l].x-In[k].x);
}
}
v+=s*(rcz[i+1]-rcz[i]);
}
printf("Case %d: %.0lf\n",t++,v);
}
return 0;
}