首页 > 其他分享 >HDU 3642 (扫描线、三维体积相交)

HDU 3642 (扫描线、三维体积相交)

时间:2024-06-12 19:44:03浏览次数:20  
标签:HDU idz int begin id 扫描线 push end 3642

题意

在三维空间中给你n个长方体,求空间中被这些长方体覆盖至少3次以上的区域的总体积。

思路

这题没给数据组数T的范围,大致看了一下其他人的都是枚举z来做的,所以我这边也是同样的做法转换成二维的扫描线来做,数组ci表示被覆盖i次的区间标记,具体扫描线怎么实现可以看我上篇博客。

  1 #define IO std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
  2 #define bug2(x,y) cout<<#x<<" is "<<x<<" "<<#y<<" is "<<y<<endl
  3 #define bug(x) cout<<#x<<" is "<<x<<endl;
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<cstdio>
  7 #include<vector>
  8 #include<tuple> 
  9 #define rs o*2+1
 10 #define ls o*2
 11 using namespace std;
 12 typedef long long ll;
 13 const int N=2e3+5;
 14 int T, kase, n, c[N*4];
 15 ll sum[4][N*4];
 16 vector<tuple<int, int, int, int, int, int>> v, g;
 17 vector<int> id;
 18 vector<int> idz;
 19 void push_up(int o, int l, int r){
 20     if (c[o] >= 3) {
 21         for (int i = 1; i <= 3 ;i++) sum[i][o] = id[r] - id[l-1];
 22     }
 23     else if (c[o] == 2) {
 24         for (int i = 1; i <= 2 ;i++) sum[i][o] = id[r] - id[l-1];
 25         if (l < r) sum[3][o] = sum[1][ls] + sum[1][rs];
 26         else sum[3][o] = 0; 
 27     }
 28     else if (c[o] == 1) {
 29         sum[1][o] = id[r] - id[l-1];
 30         if (l < r) {
 31             for(int i = 2; i <= 3 ;i++) sum[i][o] = sum[i-1][ls] + sum[i-1][rs];
 32         }
 33         else sum[2][o] = sum[3][o] = 0;
 34     }
 35     else{
 36         if (l < r) {
 37             for(int i = 1; i <= 3 ;i++) sum[i][o] = sum[i][ls] + sum[i][rs];
 38         }
 39         else sum[1][o] = sum[2][o] = sum[3][o] = 0;
 40     }
 41 } 
 42 void up(int o, int l, int r, int ql, int qr, int val){
 43     if (l >= ql && r <= qr) {
 44         c[o] += val;
 45         push_up(o, l, r);
 46         return;
 47     }
 48     int m = (l+r)/2;
 49     if (ql <= m) up(ls, l, m, ql, qr, val);
 50     if (qr > m) up(rs, m+1, r, ql, qr, val);
 51     push_up(o, l, r);
 52 }
 53 int gao(int x){
 54     return lower_bound(id.begin(), id.end(), x)-id.begin();
 55 }
 56 void init(int n){
 57     for (int i = 1; i <= 8 * n; i++) {
 58         c[i] = 0;
 59         for (int j = 1; j <= 3; j++) {
 60             sum[j][i] = 0;
 61         }
 62     }
 63 }
 64 int main(){
 65     IO;
 66     cin >> T;
 67     while (T--){
 68         cin >> n;
 69         id.clear();
 70         v.clear();
 71         int l, r, d, u, h, k;
 72         for (int i = 0; i < n; i++){
 73             cin >> l >> d >> k >> r >> u >> h;
 74             id.push_back(d);
 75             id.push_back(u);
 76             idz.push_back(h);
 77             idz.push_back(k);
 78             v.push_back(make_tuple(l, d, u, 1, k, h));
 79             v.push_back(make_tuple(r, d, u, -1, k, h));
 80         }
 81         sort(v.begin(), v.end()); 
 82         sort(id.begin(), id.end());
 83         id.erase(unique(id.begin(), id.end()), id.end());
 84         sort(idz.begin(), idz.end());
 85         idz.erase(unique(idz.begin(), idz.end()), idz.end());
 86         ll ans = 0;
 87         for (int i = 1; i < idz.size(); i++) {
 88             int pre = 0;
 89             init(n);
 90             ll res = 0;
 91             g.clear();
 92             for (auto j : v) {
 93                 int k = get<4>(j), h = get<5>(j);
 94                 if (idz[i-1] >= k && idz[i] <= h) g.push_back(j);
 95             }
 96             for (auto j : g) {
 97                 int pos = get<0>(j), d = get<1>(j), u = get<2>(j), val = get<3>(j);
 98                 res += 1ll * (pos - pre) * sum[3][1];
 99                 pre = pos;
100                 up(1, 1, id.size()-1, gao(d)+1, gao(u), val);
101             }
102             ans += res * (idz[i] - idz[i-1]);
103         }
104         printf("Case %d: %I64d\n",++kase,ans);
105     }
106 }

 

   

标签:HDU,idz,int,begin,id,扫描线,push,end,3642
From: https://www.cnblogs.com/ccsu-kid/p/18244593

相关文章

  • 扫描线
    扫描线引入扫描线一般运用在图形上面,它和它的字面意思十分相似,就是一条线在整个图上扫来扫去,它一般被用来解决图形面积、周长,以及二维数点等问题。面积问题例题1:【模板】扫描线想象有一条线从下往上扫,会将整个图像依次扫描。我们只需要计算出每一条矩形(即图中同一颜色的小矩......
  • hdu5532
    给定一个序列,询问是否能删除一个数让它成为非递减或者非递增的序列。nlogn一直过不了,所以选择了以下方式。。。因为删除一个嘛,先证明删除一个能不能是非递减的(非递增的把序列倒过来搞一次就行了)首先,对一个序列前后两个数做差比如说序列31415 做差后(即1-3,4-1,1-4,5-1)是......
  • hdu1087简单动态规划
    求最长子序列的和。dp[i]=max(dp[i],dp[j]+xx[i])。importjava.util.Arrays;importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){//TODO自动生成的方法存根Scannersc=newScanner(System.in);......
  • hdu1257最少拦截系统
    Dilworth定理通俗地讲就是对于一个偏序集,最少链划分等于最长反链长度。通俗点就是一个数列最少的不上升(<=)子序列的条数等于该数列最长上升(>)子序列的长度就是求最长有序子序列packagebag;importjava.util.Arrays;importjava.util.Scanner;publicclasshdu1257{......
  • hdu1069java
    给你n个方块,其中每个方块具有它的长宽高(方块可以任意旋转放置),方块数量不限。现在你要堆一个高塔,上面方块的长和宽必须严格小于下面方块的长和宽。问你能堆起来的最大高度。先将方块以长和宽按从小到大排序,然后从小到大以此为底,求出最大高度。dp[i]=max(dp[j])+i.height(j.x<i.x......
  • hduoj 1506(笛卡尔树)
    Problem-1506(hdu.edu.cn)题意坐标轴给定一些矩形,紧密排在一起,每个矩形宽度固定为1,问形成的图案中最大可以组成的矩形面积。思路常规思路是可以用单调栈分别找两边的合法边界,这里使用笛卡尔树。笛卡尔树实现了堆的性质,并且对原数组建立的笛卡尔树进行中序遍历为原数组的顺......
  • hdu4417(权值离散化后建立主席树)
    Problem-4417(hdu.edu.cn)马里奥是举世闻名的水管工。他“魁梧”的身材和惊人的跳跃能力让我们想起了。现在可怜的公主又遇到了麻烦,马里奥需要拯救他的爱人。我们将通往老板城堡的道路视为一条线(长度为n),在每个整数点i上都有一块高度为hi的砖。现在的问题是,如果马里奥可......
  • hdu4348(主席树区间修改)
    Problem-4348(hdu.edu.cn)BackgroundToTheMoon是一款独立游戏,于2011年11月发布,是一款由RPGMaker提供支持的角色扮演冒险游戏。《去月球》的前提是基于一种技术,该技术使我们能够永久地重建垂死之人的记忆。在这个问题上,我们将给你一个机会,实现幕后的逻辑。您已经获得了N......
  • hdu4027(线段树区间操作)
    Problem-4027(hdu.edu.cn)许多邪恶的战舰在战斗前排成一排。我们的指挥官决定使用我们的秘密武器来消灭战列舰。每艘战列舰都可以标记为耐力值。对于我们秘密武器的每一次攻击,它都可能降低连续部分战列舰的续航能力,使它们的续航力达到其原始续航力值的平方根。在我们的秘密武......
  • hdu1025java
    1:dp+二分 NlogN的复杂度2:注意road与roads区别3:注意输入不能用Scanner4:注意格式最后是要输出两个空行假设存在一个序列d[1..9]=215364897,可以看出来它的LIS长度为5。下面一步一步试着找出它。我们定义一个序列B,然后令i=1to9逐个考察这个序列。此外,我们用......