这题可以转化为求长方体体积的并,将每块地的价值看做高。然后求解就与上一篇差不多了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 60006;
int cov[maxn<<2], len[maxn<<2];
int yy[maxn];
int ss[5], zz[5];
map<int, int> my;
struct Field
{
int x1, y1, x2, y2, s;
void get()
{
scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &s);
}
}f[30001];
struct Line
{
int y1, y2, x;
int flag;
}ll[maxn];
bool cmp(Line a, Line b)
{
if (a.x == b.x)
return a.flag > b.flag;
return a.x < b.x;
}
void build(int l, int r, int rt)
{
cov[rt] = len[rt] = 0;
if (l + 1 == r) return ;
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m, r, rt << 1 | 1);
}
void pushUp(int l, int r, int rt)
{
if (cov[rt] > 0)
len[rt] = yy[r] - yy[l];
else if (cov[rt] == 0)
{
if (l + 1 == r)
len[rt] = 0;
else len[rt] = len[rt<<1] + len[rt<<1|1];
}
}
void update(int L, int R, int c, int l, int r, int rt)
{
if (L <= l && R >= r)
{
cov[rt] += c;
pushUp(l, r, rt);
return ;
}
if (l + 1 == r) return ;
int m = (l + r) >> 1;
if (L < m) update(L, R, c, l, m, rt << 1);
if (R > m) update(L, R, c, m, r, rt << 1 | 1);
pushUp(l, r, rt);
}
void addLine(int x1, int y1, int x2, int y2, int &idx)
{
ll[idx].y1 = y1;
ll[idx].y2 = y2;
ll[idx].x = x1;
ll[idx].flag = 1;
idx++;
ll[idx].y1 = y1;
ll[idx].y2 = y2;
ll[idx].x = x2;
ll[idx].flag = -1;
idx++;
}
long long solve(int n, int m)
{
sort(ll, ll + n * 2, cmp);
sort(yy, yy + n * 2);
int cnty = 1;
for (int i = 1; i < n * 2; ++i)
{
if (yy[i] != yy[cnty-1])
yy[cnty++] = yy[i];
}
for (int i = 0; i < cnty; ++i)
my[yy[i]] = i;
long long ans = 0;
build(0, cnty - 1, 1);
for (int i = 0; i < m; ++i)
{
int cnt = 0;
for (int j = 0; j < n; ++j)
{
if (ss[f[j].s] > zz[i])
addLine(f[j].x1, f[j].y1, f[j].x2, f[j].y2, cnt);
}
sort(ll, ll + cnt, cmp);
for (int j = 0; j < cnt - 1; ++j)
{
update(my[ll[j].y1], my[ll[j].y2], ll[j].flag, 0, cnty - 1, 1);
ans += (zz[i+1] - zz[i]) * (long long)len[1] * (ll[j+1].x - ll[j].x);
}
update(my[ll[cnt-1].y1], my[ll[cnt-1].y2], ll[cnt-1].flag, 0, cnty - 1, 1);
}
return ans;
}
int main()
{
int t, n, m;
scanf("%d", &t);
for (int cas = 1; cas <= t; ++cas)
{
scanf("%d %d", &n, &m);
for (int i = 1; i <= m; ++i)
scanf("%d", &ss[i]);
for (int i = 1; i <= m; ++i)
zz[i] = ss[i];
zz[0] = 0;
sort(zz, zz + m + 1);
for (int i = 0; i < n; ++i)
{
f[i].get();
yy[i*2] = f[i].y1, yy[i*2+1] = f[i].y2;
}
long long ans = solve(n, m);
printf("Case %d: %I64d\n", cas, ans);
}
}