求体积的一个比较好的题,由于m很小,直接枚举就行。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int inf=1<<29;
const int maxn=3e4+1000;
const int maxm=maxn*8;
struct Line
{
int x1;
int x2;
int y;
int flag;
int pri;
Line(){}
Line(int sx1,int sx2,int sy,int spri,int sflag)
{
x1=sx1;
x2=sx2;
y=sy;
pri=spri;
flag=sflag;
}
bool operator < (const Line &l)const
{
if(y==l.y)
return x1<l.x1;
return y<l.y;
}
}L[maxn*2];
struct Node
{
int l;
int r;
int len;
int cover;
}t[maxm];
int n,m,cnt,X[maxn*2],index[maxn*2],cntx,pri[4];
void Build(int l,int r,int index)
{
t[index].l=l;
t[index].r=r;
t[index].len=t[index].cover=0;
if(l==r)
return ;
int mid=(l+r)>>1;
Build(l,mid,index<<1);
Build(mid+1,r,index<<1|1);
}
void PushUp(int index)
{
if(t[index].cover>0)
t[index].len=X[t[index].r+1]-X[t[index].l];
else if(t[index].l==t[index].r)
t[index].len=0;
else
t[index].len=t[index<<1].len+t[index<<1|1].len;
}
void Update(int l,int r,int index,int val)
{
if(l>r)
return;
if(t[index].l==l&&t[index].r==r)
{
t[index].cover+=val;
PushUp(index);
return;
}
int mid=(t[index].l+t[index].r)>>1;
if(r<=mid)
Update(l,r,index<<1,val);
else if(l>mid)
Update(l,r,index<<1|1,val);
else
{
Update(l,mid,index<<1,val);
Update(mid+1,r,index<<1|1,val);
}
PushUp(index);
}
int main()
{
int T,cas=1;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d",&pri[i]);
cnt=cntx=0;
for(int i=0;i<n;i++)
{
int x1,x2,y1,y2,s;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&s);
L[cnt++]=Line(x1,x2,y1,pri[s],1);
L[cnt++]=Line(x1,x2,y2,pri[s],-1);
X[cntx++]=x1;
X[cntx++]=x2;
}
sort(X,X+cntx);
cntx=unique(X,X+cntx)-X;
sort(pri+1,pri+m+1);
sort(L,L+cnt);
long long ans=0;
for(int i=1;i<=m;i++)
{
int scnt=0;
Build(0,cntx,1);
for(int j=0;j<cnt;j++)
if(L[j].pri>=pri[i])
index[scnt++]=j;
for(int j=0;j<scnt-1;j++)
{
int sl=lower_bound(X,X+cntx,L[index[j]].x1)-X;
int sr=lower_bound(X,X+cntx,L[index[j]].x2)-X;
sr--;
Update(sl,sr,1,L[index[j]].flag);
ans+=(long long)t[1].len*(L[index[j+1]].y-L[index[j]].y)*(pri[i]-pri[i-1]);
}
}
printf("Case %d: %I64d\n",cas++,ans);
}
return 0;
}