zoukankan      html  css  js  c++  java
  • Get The Treasury (三维空间扫描线)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3642

    题目大意:给你n个立方体,求相交区域大于等于三次的体积和。

    题目思路:同样的利用二维扫描线去维护xOy平面的矩形的面积。 然后对于每个不同的z找到符合要求的长方体

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <map>
      6 using namespace std;
      7 const int N = 2005;
      8 struct Line {
      9     int lx, h1, h2;
     10     int flag;
     11     Line(int a, int b, int c, int d):lx(a), h1(b), h2(c), flag(d) {}
     12     bool operator < (const Line &a) const { return lx < a.lx; }
     13 };
     14 int n, flag[N << 2], cube[N][6];
     15 int tree[4][N << 2];
     16 vector<int> a, b;
     17 vector<Line> line;
     18 map<int, int> mp;
     19 
     20 void pushup(int k, int left, int right) {
     21     if (flag[k] > 2) {
     22         tree[3][k] = tree[0][k];
     23         tree[2][k] = tree[1][k] = 0;
     24     }
     25     else if (flag[k] == 2) {
     26         if (left + 1 == right) {
     27             tree[2][k] = tree[0][k];
     28             tree[1][k] = tree[3][k] = 0;
     29         }
     30         else {
     31             tree[3][k] = tree[3][k * 2] + tree[3][k * 2 + 1] + tree[2][k * 2] + tree[2][k * 2 + 1] + tree[1][k * 2] + tree[1][k * 2 + 1];
     32             tree[2][k] = tree[0][k] - tree[3][k];
     33             tree[1][k] = 0;
     34         }
     35     }
     36     else if (flag[k] == 1) {
     37         if (left + 1 == right) {
     38             tree[1][k] = tree[0][k];
     39             tree[2][k] = tree[3][k] = 0;
     40         }
     41         else {
     42             tree[3][k] = tree[3][k * 2] + tree[3][k * 2 + 1] + tree[2][k * 2] + tree[2][k * 2 + 1];
     43             tree[2][k] = tree[1][k * 2] + tree[1][k * 2 + 1];
     44             tree[1][k] = tree[0][k] - tree[3][k] - tree[2][k];
     45         }
     46     }
     47     else {
     48         if (left + 1 == right)
     49             tree[3][k] = tree[2][k] = tree[1][k] = 0;
     50         else {
     51             tree[3][k] = tree[3][k * 2] + tree[3][k * 2 + 1];
     52             tree[2][k] = tree[2][k * 2] + tree[2][k * 2 + 1];
     53             tree[1][k] = tree[1][k * 2] + tree[1][k * 2 + 1];
     54         }
     55     }
     56 }
     57 
     58 void build(int k, int left, int right) {
     59     tree[0][k] = a[right] - a[left];
     60     tree[1][k] = tree[2][k] = tree[3][k] = flag[k] = 0;
     61     if (left + 1 != right) {
     62         int mid = (left + right) / 2;
     63         build(k * 2, left, mid);
     64         build(k * 2 + 1, mid, right);
     65     }
     66 }
     67 
     68 void modify(int k, int left, int right, int l, int r, int v) {
     69     if (l <= left && right <= r)  {
     70         flag[k] += v;
     71         pushup(k, left, right);
     72         return;
     73     }
     74     int mid = (left + right) / 2;
     75     if (l < mid)
     76         modify(k * 2, left, mid, l, r, v);
     77     if (r > mid)
     78         modify(k * 2 + 1, mid, right, l, r, v);
     79     pushup(k, left, right);
     80 }
     81 
     82 int main() {
     83     int t, cas = 1;
     84     scanf("%d", &t);
     85     while (t--) {
     86         a.clear(), b.clear(), mp.clear();
     87         scanf("%d", &n);
     88         // a 记录 y ,b 记录 z
     89         for (int i = 0; i < n; i++) {
     90             scanf("%d%d%d%d%d%d", &cube[i][0], &cube[i][1], &cube[i][2], &cube[i][3], &cube[i][4], &cube[i][5]);
     91             a.push_back(cube[i][1]);
     92             a.push_back(cube[i][4]);
     93             b.push_back(cube[i][2]);
     94             b.push_back(cube[i][5]);
     95         }
     96         if (n < 3) {
     97             printf("Case %d: 0
    ", cas++);
     98             continue;
     99         }
    100         sort(a.begin(), a.end());
    101         a.erase(unique(a.begin(), a.end()), a.end());
    102         sort(b.begin(), b.end());
    103         b.erase(unique(b.begin(), b.end()), b.end());
    104         int sz = a.size(), sz2 = b.size();
    105         for (int i = 0; i < sz; i++)
    106             mp[a[i]] = i;
    107         build(1, 0, sz - 1);
    108         long long res = 0;
    109         for (int i = 0; i < sz2 - 1; i++) { // 枚举z
    110             line.clear();
    111             for (int j = 0; j < n; j++) {
    112                 if (cube[j][2] <= b[i] && cube[j][5] >= b[i + 1]) { // 找到合法的长方体
    113                     line.push_back(Line(cube[j][0], cube[j][1], cube[j][4], 1));
    114                     line.push_back(Line(cube[j][3], cube[j][1], cube[j][4], -1));
    115                 }
    116             }
    117             sort(line.begin(), line.end());
    118             int sz3 = line.size();
    119             for (int j = 0; j < sz3; j++) {
    120                 if (j != 0)
    121                     res += (b[i + 1] - b[i]) * (line[j].lx - line[j - 1].lx) * (long long)tree[3][1];
    122                 modify(1, 0, sz - 1, mp[line[j].h1], mp[line[j].h2], line[j].flag); // 和二维的扫描线是一样的
    123             }
    124         }
    125         printf("Case %d: %lld
    ", cas++, res);
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    Python爬虫技术--基础篇--函数式编程(上篇)
    Python爬虫技术--基础篇--Python高级特性
    Python爬虫技术--基础篇--函数(下篇)
    Python爬虫技术--基础篇--函数(上篇)
    Python爬虫技术--基础篇--字典和集合
    Python爬虫技术--基础篇--列表和元组
    1013 数素数
    1012 数字分类
    1010 一元多项式求导
    1011 A+B 和 C
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11735899.html
Copyright © 2011-2022 走看看