HDU 3642 Get The Treasury[离散化 + 扫描线 + 线段树]
http://acm.hdu.edu.cn/showproblem.php?pid=3642
给空间中n个立方体,求被这些立方体覆盖过至少3次的区域的体积。
数据范围:
z坐标范围才1000,直接枚举一下。相当于将这些立方体切成一层层的,每层厚度为1,分别求出每一层至少被覆盖3次的区域的面积即可。也就是对每一层z,找出包含这层的立方体,将它们的xy坐标抽出来,再用平面求被覆盖多次的面积的方法求解,(here)
#include<bits/stdc++.h>
using namespace std;
typedef long long int64;
#define debug(x) cout<<"debug "<<x<<endl;
#define rep(i,f,t) for(int i = (f),_end = (t); i <= _end; ++i)
#define clr(c,x) memset(c,x,sizeof(c));
#define MID int mid = (L+R)>>1;
#define CHD int lc = node<<1,rc = node<<1|1;
struct Node{
int z1,z2,x1,x2,y1,y2;
Node(int z1,int z2,int x1,int y1,int x2,int y2)
:z1(z1),z2(z2),x1(x1),x2(x2),y1(y1),y2(y2){}
};
struct Node2{
int x,y1,y2;
int flag;
Node2(int x,int y1,int y2,int f)
:x(x),y1(y1),y2(y2),flag(f){}
bool operator< (const Node2 &n2) const{
if(x==n2.x)return flag==1 && n2.flag==-1;
return x < n2.x;
}
};
vector<int> vs;
vector<Node> cube;
vector<Node2> line;
const int maxn = 2002<<2;
struct sgt{
int cov[maxn];
int64 sum[maxn][4];
void init(){
clr(cov,0);
clr(sum,0);
}
void maintain(int node,int L,int R){
int tot = vs[R]-vs[L-1];
clr(sum[node], 0);
rep(i,1,min(3,cov[node]))sum[node][i] = tot;
if(L==R)return;
CHD;
rep(i,cov[node]+1,3){
sum[node][i] = sum[lc][i-cov[node]]+sum[rc][i-cov[node]];
}
}
double query(){
return sum[1][3];
}
void update(int from,int to,int val,int node,int L,int R){
if(from <= L && R <= to){
cov[node] += val;
}else{
MID;CHD;
if(from <= mid)update(from,to,val,lc,L,mid);
if(to > mid) update(from,to,val,rc,mid+1,R);
}
maintain(node,L,R);
}
}tree;
void pre(){
sort(vs.begin(),vs.end());
vs.erase(unique(vs.begin(),vs.end()),vs.end());
rep(i,0,cube.size()-1){
cube[i].y1 = lower_bound(vs.begin(),vs.end(),cube[i].y1) - vs.begin();
cube[i].y2 = lower_bound(vs.begin(),vs.end(),cube[i].y2) - vs.begin();
}
}
int64 solve(int z){
line.clear();
tree.init();
rep(i,0,cube.size()-1){
if(cube[i].z1>z || cube[i].z2<=z)continue;
line.push_back(Node2(cube[i].x1,cube[i].y1,cube[i].y2,1));
line.push_back(Node2(cube[i].x2,cube[i].y1,cube[i].y2,-1));
}
sort(line.begin(),line.end());
int64 ans = 0;
int x = line[0].x;
rep(i,0,line.size()-1){
int64 len = tree.query();
ans += len*(line[i].x-x);
x = line[i].x;
tree.update(line[i].y1+1,line[i].y2,line[i].flag,1,1,vs.size()-1);
}
return ans;
}
int main(){
int n;
int casn;
scanf("%d",&casn);
rep(cas,1,casn){
cube.clear();
vs.clear();
scanf("%d",&n);
int from = 505,to = -1;
rep(i,1,n){
int x1,y1,x2,y2,z1,z2;
scanf("%d%d%d%d%d%d",&x1,&y1,&z1,&x2,&y2,&z2);
vs.push_back(y1);
vs.push_back(y2);
cube.push_back(Node(z1,z2,x1,y1,x2,y2));
from = min(from,z1);
to = max(to,z2);
}
pre();
int64 ans = 0;
rep(z2,from,to){
int64 res = solve(z2);
ans += res;
}
printf("Case %d: %lld\n",cas,ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。