HDU 3642 Get The Treasury[离散化 + 扫描线 + 线段树]
来源:互联网 发布:linux安装vmware 编辑:程序博客网 时间:2024/06/06 17:06
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;}
0 0
- HDU 3642 Get The Treasury(离散化+线段树:扫描线)
- HDU 3642 Get The Treasury[离散化 + 扫描线 + 线段树]
- HDU 3642——Get The Treasury(线段树+扫描线+离散化+体积交多次)
- HDU 3642 Get The Treasury 【线段树】【扫描线】
- hdu3642-Get The Treasury 线段树+扫描线+离散化 求三维体积并
- hdu 3642 Get The Treasury(扫描线)
- HDU 3642 Get The Treasury (线段树、扫描线求立方体体积交)
- HDU 3642 Get The Treasury(体积并+覆盖三次+线段树+扫描线)
- HDU 3642 Get The Treasury(体积并,离散化)
- HDU 3642 Get The Treasury (线段树扫描线进阶--求长方体重叠3次或以上的体积)
- HDU 3642 Get The Treasury(线段树+扫描线求面积【再升级版(三维)】)
- hdu 3642 Get The Treasury (三维的扫描线)
- hdu 3642 Get The Treasury(扫描线、立方体交)
- hdoj 3642 Get The Treasury 【线段树 扫描线 求立方体积交】
- hdu 3642 Get The Treasury(线段树求体积并)
- hdu-3642--Get The Treasury-线段树求面积并
- HDU 3642 Get The Treasury(线段树)
- hdu3642 Get The Treasury--线段树 & 扫描线 & 面积并(待解决)
- 运算符
- Binary Tree Right Side View
- 如何在富途证券开户,富途证券如何开户,如何开通港股账户,如何炒港股
- C语言函数string.h 之 内存copy函数memcpy
- 解答:为什么eclipse新建Android项目时无法打开build sdk下拉菜单,无法完成新建?
- HDU 3642 Get The Treasury[离散化 + 扫描线 + 线段树]
- LeetCode OJ 1Two Sum
- matlab ( octave ) imwrite 保存图像详解
- 黑马程序员——Java基础视频笔记(五):集合详解
- Unity IOS下的热更新研究(转)
- unity mono 编译(转)
- Java中的static静态
- Android TextSwitcher官方使用教程
- n个节点,m个相互连接的边,边为a【m】,求最短路径