题意:
原始题意就不说了。抽象出来就是给你n个底面在xoy平面与坐标轴平行的立方体。他们之间可以重叠。问体积并是多少。
思路:
和求面积并的思路类似。用高度(价值)把立方体分成很多段。然后一段一段求体积就好。
详细见代码:
#include
#include
#include
using namespace std;
const int maxn=30010;
typedef long long ll;
#define lson L,mid,ls
#define rson mid+1,R,rs
struct node
{
int x1,x2,h,tag;//面积并用的值。tag表示加边还是减边
int p;//存第三维高度。
node(){}
node(int a,int b,int c,int d,int e):x1(a),x2(b),h(c),tag(d),p(e){}
bool operator <(const node &op) const
{
return h>1;
build(lson);
build(rson);
}
void update(int L,int R,int rt,int l,int r,int d)
{
if(l<=L&&R<=r)
{
cov[rt]+=d;
len[rt]=cov[rt]?H[R+1]-H[L]:(L==R?0:len[rt<<1]+len[rt<<1|1]);
//printf("%d -> %d len %d\n",H[L],H[R+1],len[rt]);
return;
}
int ls=rt<<1,rs=ls|1,mid=(L+R)>>1;
if(l<=mid)
update(lson,l,r,d);
if(r>mid)
update(rson,l,r,d);
len[rt]=cov[rt]?H[R+1]-H[L]:len[ls]+len[rs];
//printf("%d -> %d len %d\n",H[L],H[R+1],len[rt]);
}
int main()
{
int t,n,m,i,j,cas=1,ct,cnt;
int x1,x2,y1,y2,ch,ns;
ll ans,tp;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
scanf("%d",&val[i]);
ans=ns=ct=0;
for(i=1;i<=n;i++)
{
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&ch);
seg[ns++]=node(x1,x2,y1,1,val[ch]);
seg[ns++]=node(x1,x2,y2,-1,val[ch]);
H[ct++]=x1,H[ct++]=x2;
}
sort(H,H+ct);
ct=unique(H,H+ct)-H;
sort(seg,seg+ns);
sort(val+1,val+m+1);
for(i=0;ival[i])
tmp[cnt++]=seg[j];
build(0,ct-2,1);
for(j=tp=0,cnt--;j