• Get The Treasury HDU


    题意:给你n个长方体,求至少相交三次的体积。

    思路:1、z的数量较小,可以枚举z,对于两个z之间的夹层用二维扫描线

         2、对于每个夹层,用二维扫描线求出相交至少三次的面积和,最后乘上一个△z(夹层的高度)即可

    易错点:(我的天,第一次写完好多bug,都是处理不当导致的,以后一定要避免了!)

      1、各个数组的下标要么全都是从0开始,要么都是从1开始,我比较喜欢从1开始。

      2、unique函数使用的时候后面减掉的是(数组的首地址 + 1),lower_bound函数减掉的是数组的首地址;因为unique获得的是数组元素的个数,而lower_bound获得的是元素的下标。(这些一定要记清楚了,以后写代码可以加快速度)

    代码:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const int maxn = 4010;
      5 int z[maxn];
      6 int x[maxn];
      7 
      8 struct point
      9 {
     10     int x, y, z;
     11     point(int a = 0, int b = 0, int c = 0) : x(a), y(b), z(c){}
     12 };
     13 struct cube
     14 {
     15     point a, b;
     16 }c[maxn];
     17 struct edge
     18 {
     19     int x1, x2;
     20     int y;
     21     int flag;
     22     edge(int a = 0, int b = 0, int c = 0, int d = 0) : x1(a), x2(b), y(c), flag(d){}
     23     bool operator< (const edge& b)const
     24     {
     25         return y < b.y;
     26     }
     27 }e[maxn];
     28 
     29 struct node
     30 {
     31     int l, r;
     32     int s;
     33     int len1, len2, len3;
     34 }t[maxn << 2];
     35 
     36 void pushup(int tar)
     37 {
     38     if (t[tar].s)
     39         t[tar].len1 = x[t[tar].r + 1] - x[t[tar].l];
     40     else if (t[tar].l == t[tar].r)
     41         t[tar].len1 = 0;
     42     else t[tar].len1 = t[tar << 1].len1 + t[tar << 1 | 1].len1;
     43 
     44     if (t[tar].s >= 2)
     45         t[tar].len2 = x[t[tar].r + 1] - x[t[tar].l];
     46     else if (t[tar].l == t[tar].r)
     47         t[tar].len2 = 0;
     48     else if (t[tar].s == 1)
     49         t[tar].len2 = t[tar << 1].len1 + t[tar << 1 | 1].len1;
     50     else t[tar].len2 = t[tar << 1].len2 + t[tar << 1 | 1].len2;
     51 
     52     if (t[tar].s >= 3)
     53         t[tar].len3 = x[t[tar].r + 1] - x[t[tar].l];
     54     else if (t[tar].l == t[tar].r)
     55         t[tar].len3 = 0;
     56     else if (t[tar].s == 2)
     57         t[tar].len3 = t[tar << 1].len1 + t[tar << 1 | 1].len1;
     58     else if (t[tar].s == 1)
     59         t[tar].len3 = t[tar << 1].len2 + t[tar << 1 | 1].len2;
     60     else t[tar].len3 = t[tar << 1].len3 + t[tar << 1 | 1].len3;
     61 }
     62 
     63 void build(int l, int r, int tar)
     64 {
     65     t[tar].l = l, t[tar].r = r, t[tar].s = t[tar].len1 = t[tar].len2 = t[tar].len3 = 0;
     66     if (l == r) return;
     67     int mid = (l + r) >> 1;
     68     build(l, mid, tar << 1), build(mid + 1, r, tar << 1 | 1);
     69 }
     70 
     71 void update(int l, int r, int v, int tar)
     72 {
     73     if (t[tar].l == l && t[tar].r == r)
     74     {
     75         t[tar].s += v;
     76         pushup(tar);
     77         return;
     78     }
     79     int mid = (t[tar].l + t[tar].r) >> 1;
     80     if (r <= mid) update(l, r, v, tar << 1);
     81     else if (l > mid) update(l, r, v, tar << 1 | 1);
     82     else update(l, mid, v, tar << 1), update(mid + 1, r, v, tar << 1 | 1);
     83     pushup(tar);
     84 }
     85 
     86 int main()
     87 {
     88     int T; cin >> T;
     89     int cases = 0;
     90     while (T--)
     91     {
     92         int n; cin >> n;
     93         int numz = 0, numx = 0;
     94         int nume = 0;
     95 
     96         for (int i = 1; i <= n; i++)
     97         {
     98             scanf("%d%d%d%d%d%d", &c[i].a.x, &c[i].a.y, &c[i].a.z, &c[i].b.x, &c[i].b.y, &c[i].b.z);
     99             z[++numz] = c[i].a.z, z[++numz] = c[i].b.z;
    100         }
    101         sort(z + 1, z + 1 + numz);
    102         numz = unique(z + 1, z + 1 + numz) - z - 1;
    103         ll res = 0;
    104         for (int i = 1; i < numz; i++)
    105         {
    106             nume = numx = 0;
    107             for (int j = 1; j <= n; j++)
    108                 if (c[j].a.z <= z[i] && c[j].b.z > z[i])
    109                 {
    110                     e[++nume] = edge(c[j].a.x, c[j].b.x, c[j].a.y, 1);
    111                     e[++nume] = edge(c[j].a.x, c[j].b.x, c[j].b.y, -1);
    112                     x[++numx] = c[j].a.x, x[++numx] = c[j].b.x;
    113                 }
    114             sort(x + 1, x + 1 + numx);
    115             numx = unique(x + 1, x + 1 + numx) - x - 1;
    116             build(1, numx - 1, 1);
    117             sort(e + 1, e + 1 + nume);
    118             ll res1 = 0;
    119             for (int j = 1; j < nume; j++)
    120             {
    121                 int x1, x2;
    122                 x1 = lower_bound(x + 1, x + 1 + numx, e[j].x1) - x;
    123                 x2 = lower_bound(x + 1, x + 1 + numx, e[j].x2) - x;
    124                 update(x1, x2 - 1, e[j].flag, 1);
    125                 res1 += (long long)t[1].len3 * (e[j + 1].y - e[j].y);
    126             }
    127             res += res1 * (z[i + 1] - z[i]);
    128         }
    129         printf("Case %d: %lld
    ", ++cases, res);
    130     }
    131 }
  • 相关阅读:
    Django—使用后台管理Models
    Django—开发具体流程
    Sqlite—数据库管理与表管理
    Sqlite—数据类型
    Python—实现钉钉后台开发
    Xdebug文档(一)基本特性
    FHS定义的Linux目录树
    【转】给Windows + Apache 2.2 + PHP 5.3 安装PHP性能测试工具 xhprof
    【转】UTF-8汉字正则表达式
    【转】Nginx区分PC或手机访问不同网站
  • 原文地址:https://www.cnblogs.com/liuwenhan/p/11611453.html
Copyright © 2020-2023  润新知