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代表该区 ...
随机推荐
- AJAX 加载效果(遮盖层)
//创建遮罩层函数体 function createMask(){ var node=document.createElement('div'); node.setAttribute('id','ba ...
- 05.从0实现一个JVM语言之目标平台代码生成-CodeGenerator
从0实现JVM语言之目标平台代码生成-CodeGenerator 源码github仓库, 如果这个系列文章对你有帮助, 希望获得你的一个star 本节相关代码生成package地址 阶段性的告别 非常 ...
- JAVA-常用集合类型转换例子
package com.net.xinfang.reflect; import java.util.ArrayList; import java.util.Arrays; import java.ut ...
- Nuxt.js vue服务端渲染
一.为什么要用Nuxt.js 原因其实不用多说,就是利用Nuxt.js的服务端渲染能力来解决Vue项目的SEO问题. 二.Nuxt.js和纯Vue项目的简单对比 1. build后目标产物不同 vue ...
- java实现简易的图书馆管理系统
比较适合新手练手的一个简易项目 直接上源码 Book package code; /** * @author ztr * @version 创建时间:2021年3月4日 下午8:21:40 * 类说明 ...
- DenseNet的个人总结
DenseNet这篇论文是在ResNet之后一年发表的,由于ResNet在当时引起了很大的轰动,所以DenseNet也将ResNet作为了主要的对比方法,读起来还是比较容易的,全篇只有两个数学公式,也 ...
- 翻译:《实用的Python编程》06_03_Producers_consumers
目录 | 上一节 (6.2 自定义迭代) | 下一节 (6.4 生成器表达式) 6.3 生产者,消费者和管道 生成器在设置各种生产者/消费者问题(producer/consumer problems) ...
- Git 上传项目到 Github
Git 上传项目到 Github 该文章主要讲解Git 上传项目到 Github,Gitee同理 配置Git 下载.安装Git 下载后一路(傻瓜式安装)直接安装即可 如果第一次使用git的话,需要设置 ...
- [2020年10月28日普级组]1405.小B浇花
区 间 和 的 和 区间和的和 区间和的和 题目解析 就直接模拟,从最低的花的高度向最高的花的高度枚举,如果当循环变量的值到达了顶峰,但还有花的数量大于2的,就把循环上线加一(所以数组要开大些) Co ...
- C#中protobuf-net的编码结构及使用方法
目录 protobuf-net简介 ProtoBuf编码原理 编码结构 解析一个编码结果 使用方法 参考资料 protobuf-net简介 Protocol Buffer(简称Protobuf) 是 ...