设为首页 加入收藏

TOP

hdu 3642 Get The Treasury(扫描线)
2015-07-20 17:30:21 来源: 作者: 【 】 浏览:2
Tags:hdu 3642 Get The Treasury 扫描

题目链接:hdu 3642 Get The Treasury

题目大意:三维坐标系,给定若干的长方体,问说有多少位置被覆盖3次以上。

解题思路:扫描线,将第三维分离出来,就是普通的二维扫描线,然后对于每个节点要维护覆盖0,1,2,3以上这4种的覆盖面积。

#include 
   
     #include 
    
      #include 
     
       #include 
      
        using namespace std; const int maxn = 4005; vector
       
         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
        
          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; }
        
       
      
     
    
   
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 3954 Level up(线段树) 下一篇UVA 12034 Race (递推神马的)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·每日一道面试题-多线 (2025-12-26 06:20:17)
·java项目中哪些地方 (2025-12-26 06:20:14)
·Java真的是要没落了 (2025-12-26 06:20:12)
·C++ Lambda表达式保 (2025-12-26 05:49:45)
·C++ Lambda表达式的 (2025-12-26 05:49:42)