hdu3255 线段树扫描线求体积
题意:
给你n个矩形,每个矩形上都有一个权值(该矩形单位面积的价值),矩形之间可能重叠,重叠部分的权值按照最大的算,最后问这n个矩形组成的图形的最大价值。
思路:
线段树扫描线求长方体体积,对于求体积,如果理解求面积的过程,求体积也很容易理解,就是先一层一层的求面积,然后把面积当成"当前所覆盖的线段",以长方体的高的方向更新,不是很容易说清楚,看下代码就懂了,就体积的时候就是先求出一层面积,然后在用一层一层的面积更新体积,具体看代码吧,应该很容易理解,说着感觉很费劲。
- #include<stdio.h>
- #include<string.h>
- #include<algorithm>
- #define N 65000
- #define Nmax 300000
- #define lson l ,mid ,t << 1
- #define rson mid ,r ,t << 1 | 1
- using namespace std;
- typedef struct
- {
- __int64 l ,r ,h ,mk;
- }EDGE;
- typedef struct
- {
- __int64 x1 ,x2 ,y1 ,y2;
- __int64 pri;
- }NODE;
- EDGE edge[N];
- NODE node[33000];
- __int64 len[Nmax] ,cnt[Nmax];
- __int64 tmp[Nmax] ,num[Nmax];
- __int64 price[5];
- bool camp(EDGE a ,EDGE b)
- {
- return a.h < b.h;
- }
- int search(int id ,__int64 now)
- {
- int low ,up ,mid ,Ans;
- low = 1 ,up = id;
- while(low <= up)
- {
- mid = (low + up) >> 1;
- if(now <= num[mid])
- {
- Ans = mid;
- up = mid - 1;
- }
- else low = mid + 1;
- }
- return Ans;
- }
- void Pushup(__int64 l ,__int64 r ,__int64 t)
- {
- if(cnt[t]) len[t] = num[r] - num[l];
- else if(l + 1 == r) len[t] = 0;
- else len[t] = len[t<<1] + len[t<<1|1];
- }
- void Update(__int64 l ,__int64 r ,__int64 t ,__int64 a ,__int64 b ,__int64 c)
- {
- if(l == a && r == b)
- {
- cnt[t] += c;
- Pushup(l ,r ,t);
- return ;
- }
- __int64 mid = (l + r) >> 1;
- if(b <= mid) Update(lson ,a ,b ,c);
- else if(a >= mid) Update(rson ,a ,b ,c);
- else
- {
- Update(lson ,a ,mid ,c);
- Update(rson ,mid ,b ,c);
- }
- Pushup(l ,r ,t);
- }
- __int64 solve(int n ,int m)
- {
- __int64 Ans = 0 ,i ,id;
- sort(price + 1 ,price + m + 1);
- price[0] = 0;
- for(int ii = 1 ;ii <= m ;ii ++)
- {
- int nn = 0;
- for(id = 0 ,i = 1 ;i <= n ;i ++)
- {
- if(node[i].pri < price[ii]) continue;
- nn += 2;
- edge[++id].l = node[i].x1;
- edge[id].r = node[i].x2 ,edge[id].h = node[i].y1 ,edge[id].mk = 1;
- tmp[id] = node[i].x1;
- edge[++id].l = node[i].x1;
- edge[id].r = node[i].x2 ,edge[id].h = node[i].y2 ,edge[id].mk = -1;
- tmp[id] = node[i].x2;
- }
- sort(tmp + 1 ,tmp + id + 1);
- id = 0;
- for(i = 1 ;i <= nn ;i ++)
- if(i == 1 || tmp[i] != tmp[i-1])
- num[++id] = tmp[i];
- sort(edge + 1 ,edge + nn + 1 ,camp);
- memset(len ,0 ,sizeof(len));
- memset(cnt ,0 ,sizeof(cnt));
- __int64 ans = 0;
- edge[0].h = edge[1].h;
- for(i = 1 ;i <= nn ;i ++)
- {
- ans += len[1] * (edge[i].h - edge[i-1].h);
- __int64 ll = search(id ,edge[i].l);
- __int64 rr = search(id ,edge[i].r);
- Update(1 ,nn ,1 ,ll ,rr ,edge[i].mk);
- }
- Ans += ans * (price[ii] - price[ii-1]);
- }
- return Ans;
- }
- int main ()
- {
- int t ,n ,m ,cas = 1;
- scanf("%d" ,&t);
- while(t--)
- {
- scanf("%d %d" ,&n ,&m);
- for(int i = 1 ;i <= m ;i ++)
- scanf("%I64d" ,&price[i]);
- for(int i = 1 ;i <= n ;i ++)
- {
- scanf("%I64d %I64d %I64d %I64d %I64d" ,&node[i].x1 ,&node[i].y2 ,&node[i].x2 ,&node[i].y1 ,&node[i].pri);
- node[i].pri = price[node[i].pri];
- }
- printf("Case %d: %I64d\n" ,cas ++ ,solve(n ,m));
- }
- return 0;
- }
hdu3255 线段树扫描线求体积的更多相关文章
- 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)
D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- 【POJ-2482】Stars in your window 线段树 + 扫描线
Stars in Your Window Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11706 Accepted: ...
- HDU 4419 Colourful Rectangle --离散化+线段树扫描线
题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...
- BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤
3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...
- BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞
看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...
- hdu 5091(线段树+扫描线)
上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...
- POJ1151+线段树+扫描线
/* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
随机推荐
- 译文《最常见的10种Java异常问题》
封面:洛小汐 译者:潘潘 知彼知己,方能百战不殆. 前言 本文总结了有关Java异常的十大常见问题. 目录 检查型异常(checked) vs. 非检查型异常(Unchecked) 异常管理的最佳实践 ...
- 微信小程序在Android和Ios端的获取时间兼容性问题
an端 var time = new Date() 例如:2020-01-01 01:01:00 ios端 var time = new Date() 例如:2020/01/01 01:01:00 ...
- jQuery学习笔记(1) 初识jQuery
目录 目录 引用 注意 HelloWorldHelloWorld! jQueryjQuery对象和DOMDOM对象的相互转换 冲突的解决 引用 本地文件引用: <script src=" ...
- python-递归函数和内置函数笔记汇总
1. def syz(*args) # *args 参数组 不必填,不限制参数的个数 参数组不常用 2.def sys2(**kwargs): #关键字参数 3.递归函数, 不常 ...
- 【linux】驱动-5-驱动框架分层分离&实战
目录 前言 5. 分离分层 5.1 回顾-设备驱动实现 5.2 分离分层 5.3 设备 5.4 驱动 5.5 系统,模块 5.6 Makefile 参考: 前言 5. 分离分层 本章节记录实现LED驱 ...
- LevelDB 源码解析之 Random 随机数
GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区: https://bbs.huaweicloud.com/ ...
- MarkDown-简单学习
标题 注意:首部添加1-6个"#"号来设置标题大小: 字体 1:粗体 (注意:首尾同时添加2个"*"号来设置) 2:斜体 (注意:首尾同时添加1个"* ...
- Docker遇到的异常和注意点
Docker遇到的异常和注意点 整理一些使用docker的时候,遇到的问题和解决办法 遇到的一些异常和解决方法 删除镜像时出现: Error response from daemon: conflic ...
- ls(list)命令详解及生产使用示例
文件有文件名与数据,在linux上被分为两个部分:用户数据(user data)与元数据(metadata) 用户数据,即文件数据块(data block),数据块是记录文件真实内容的地方,我们将其称 ...
- 【设计模式】- 生成器模式(Builder)
生成器模式 建造者模式.Builder 生成器模式 也叫建造者模式,可以理解成可以分步骤创建一个复杂的对象.在该模式中允许你使用相同的创建代码生成不同类型和形式的对象. 生成器的结构模式 生成器(Bu ...