这题没思路,zxl童鞋说,类似上题。。。豁然开朗。。。><
想了想,这个就是长方体并啦~~因为这个每个方块的结果是x * y * price,把price当成 z 轴即可。
可以统一设为x1, y1, 0 x2,y2,price 的一个长方体,求并即可。
上个代码改改就没问题了。。
数组开小WA了一次。。哎。
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define FOR(i,s,t) for(int i=(s); i<(t); i++)
#define BUG puts("here!!!")
#define STOP system("pause")
#define file_r(x) freopen(x, "r", stdin)
#define file_w(x) freopen(x, "w", stdout)
using namespace std;
const int MAX = 60010;
typedef __int64 LL;
int z[10], y[MAX], cnty, cntz;
struct point{
int x, y, z;
point(){}
point(int xx, int yy, int zz):x(xx), y(yy), z(zz){}
};
struct Tnode{ // 一维线段树
int l,r,cover, slen;
int len() { return r - l;}
int mid() { return MID(l,r);}
bool in(int ll,int rr) { return l >= ll && r <= rr; }
void lr(int ll,int rr){ l = ll; r = rr;}
};
struct box{ // 长方体定义
point a, b;
};
struct Sline{int x,y1,y2,flag;}; // 扫描线定义
Tnode node[MAX<<2];
box bo[MAX];
Sline l[MAX];
void add_line(int x1,int y1,int x2,int y2,int &cnt)
{
l[cnt].x = x1; l[cnt].y1 = y1; l[cnt].y2 = y2;
l[cnt++].flag = 1;
l[cnt].x = x2; l[cnt].y1 = y1; l[cnt].y2 = y2;
l[cnt++].flag = -1;
}
bool cmp(Sline a, Sline b)
{
if( a.x == b.x )
return a.flag > b.flag;
return a.x < b.x;
}
void Build(int t,int l,int r)
{
node[t].lr(l, r);
node[t].cover = node[t].slen = 0;
if( node[t].l == node[t].r - 1 )
return ;
int mid = MID(l,r);
Build(L(t),l,mid);
Build(R(t),mid,r);
}
void Updata_len(int t)
{
if( node[t].cover >= 1)
node[t].slen = y[node[t].r] - y[node[t].l];
else
{
if( node[t].len() == 1 )
node[t].slen = 0;
else
node[t].slen = node[L(t)].slen + node[R(t)].slen;
}
}
void Updata(int t, Sline p)
{
if( y[node[t].l] >= p.y1 && y[node[t].r] <= p.y2 )
{
node[t].cover += p.flag;
Updata_len(t);
return ;
}
if( node[t].len() == 1 ) return ;
int mid = node[t].mid();
if( p.y1 < y[mid] ) Updata(L(t), p);
if( p.y2 > y[mid] ) Updata(R(t), p);
Updata_len(t);
}
LL solve(int n)
{
sort(y, y+cnty);
sort(z, z+cntz);
cnty = unique(y, y+cnty) - y;
cntz = unique(z, z+cntz) - z;
LL ans = 0;
Build(1, 0, cnty-1);
FOR(i, 0, cntz-1)
{
LL area = 0;
int cnt = 0;
FOR(k, 0, n)
if( bo[k].a.z <= z[i] && bo[k].b.z > z[i] )
add_line(bo[k].a.x, bo[k].a.y, bo[k].b.x, bo[k].b.y, cnt);
sort(l, l+cnt, cmp);
Updata(1, l[0]);
FOR(k, 1, cnt)
{
area += node[1].slen *1ll* (l[k].x - l[k-1].x);
Updata(1, l[k]);
}
ans += area * (z[i+1] - z[i]);
}
return ans;
}
int main()
{
int ncases, ind = 1, n, x1, x2, y1, y2, id;
scanf("%d", &ncases);
while( ncases-- )
{
scanf("%d%d", &n, &cntz);
cnty = 0;
FOR(i, 0, cntz)
scanf("%d", &z[i]);
FOR(i, 0, n)
{
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &id);
id--;
if( x1 > x2 ) swap(x1, x2);
if( y1 > y2 ) swap(y1, y2);
bo[i].a = point(x1, y1, 0);
bo[i].b = point(x2, y2, z[id]);
y[cnty++] = y1;
y[cnty++] = y2;
}
z[cntz++] = 0;
LL ans = solve( n );
printf("Case %d: %I64d\n", ind++, ans);
}
return 0;
}