hdu 3642 Get The Treasury(扫描线)
来源:互联网 发布:protobuf.min.js 编辑:程序博客网 时间:2024/06/05 03:03
题目链接:hdu 3642 Get The Treasury
题目大意:三维坐标系,给定若干的长方体,问说有多少位置被覆盖3次以上。
解题思路:扫描线,将第三维分离出来,就是普通的二维扫描线,然后对于每个节点要维护覆盖0,1,2,3以上这4种的覆盖面积。
#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int maxn = 4005;vector<int> pos;#define lson(x) ((x)<<1)#define rson(x) (((x)<<1)|1)int lc[maxn << 2], rc[maxn << 2], v[maxn << 2], s[maxn << 2][5];inline void pushup(int u) { memset(s[u], 0, sizeof(s[u])); if (v[u] >= 3) s[u][3] = pos[rc[u]+1] - pos[lc[u]]; else { if (lc[u] == rc[u]) s[u][v[u]] = pos[rc[u]+1] - pos[lc[u]]; else if (v[u] == 2) { s[u][2] = s[lson(u)][0] + s[rson(u)][0]; for (int i = 1; i <= 3; i++) s[u][3] += s[lson(u)][i] + s[rson(u)][i]; } else if (v[u] == 1) { s[u][1] = s[lson(u)][0] + s[rson(u)][0]; s[u][2] = s[lson(u)][1] + s[rson(u)][1]; for (int i = 2; i <= 3; i++) s[u][3] += s[lson(u)][i] + s[rson(u)][i]; } else { for (int i = 0; i <= 3; i++) s[u][i] = s[lson(u)][i] + s[rson(u)][i]; } }}inline void maintain(int u, int d) { v[u] += d; pushup(u);}void build (int u, int l, int r) { lc[u] = l; rc[u] = r; v[u] = 0; if (l == r) { maintain(u, 0); return ; } int mid = (l + r) / 2; build (lson(u), l, mid); build (rson(u), mid + 1, r); pushup(u);}void modify (int u, int l, int r, int d) { if (l <= lc[u] && rc[u] <= r) { maintain(u, d); return; } int mid = (lc[u] + rc[u]) / 2; if (l <= mid) modify(lson(u), l, r, d); if (r > mid) modify(rson(u), l, r, d); pushup(u);}struct Seg { int x, l, r, d; Seg (int x = 0, int l = 0, int r = 0, int d = 0) { this->x = x; this->l = l; this->r = r; this->d = d; }};typedef long long ll;vector<Seg> g[1005];inline bool cmp (const Seg& a, const Seg& b) { return a.x < b.x;}void init () { int n, x1, x2, y1, y2, z1, z2; scanf("%d", &n); for (int i = 0; i <= 1000; i++) g[i].clear(); for (int i = 0; i < n; i++) { scanf("%d%d%d%d%d%d", &x1, &y1, &z1, &x2, &y2, &z2); for (int i = z1; i < z2; i++) { g[i + 500].push_back(Seg(x1, y1, y2, 1)); g[i + 500].push_back(Seg(x2, y1, y2, -1)); } }}inline int find (int k) { return lower_bound(pos.begin(), pos.end(), k) - pos.begin();}ll solve (int idx) { if (g[idx].size() == 0) return 0; ll ret = 0; pos.clear(); sort(g[idx].begin(), g[idx].end(), cmp); for (int i = 0; i < g[idx].size(); i++) { pos.push_back(g[idx][i].l); pos.push_back(g[idx][i].r); } sort(pos.begin(), pos.end()); build(1, 0, pos.size()); for (int i = 0; i < g[idx].size(); i++) { modify(1, find(g[idx][i].l), find(g[idx][i].r) - 1, g[idx][i].d); if (i + 1 != g[idx].size()) ret += 1LL * s[1][3] * (g[idx][i+1].x - g[idx][i].x); } return ret;}int main () { int cas; scanf("%d", &cas); for (int kcas = 1; kcas <= cas; kcas++) { init(); ll ans = 0; for (int i = 0; i <= 1000; i++) ans += solve(i); printf("Case %d: %I64d\n", kcas, 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 【线段树】【扫描线】
- 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 (线段树、扫描线求立方体体积交)
- hdu 3642 Get The Treasury 扫描线求长方体体积交
- HDU 3642 Get The Treasury(离散化+线段树:扫描线)
- Get The Treasury - HDU 3642 扫描线 重复三次的体积
- 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(线段树+扫描线求面积【再升级版(三维)】)
- hdoj 3642 Get The Treasury 【线段树 扫描线 求立方体积交】
- repo 的安装使用
- Java流与文件操作
- ASP.NET页面生命周期
- ACM~大数加法&&hdu题目样例
- 存储过程语法及实例
- hdu 3642 Get The Treasury(扫描线)
- 开发笔记总结
- 2014年至今参与的五个项目总结
- Adapter
- 黑马程序员---------Java面向对象——JavaBean内省
- 飘逸的python - 装饰器的本质
- linux实用命令
- sql优化(where条件中的''in''在逻辑上相当于............)
- git一些常用到命令