题意:

      给你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 线段树扫描线求体积的更多相关文章

  1. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  2. Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)

    题目链接:http://codeforces.com/contest/522/problem/D 题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...

  3. 【POJ-2482】Stars in your window 线段树 + 扫描线

    Stars in Your Window Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11706   Accepted:  ...

  4. HDU 4419 Colourful Rectangle --离散化+线段树扫描线

    题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...

  5. BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤

    3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...

  6. BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞

    看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...

  7. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  8. POJ1151+线段树+扫描线

    /* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...

  9. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

随机推荐

  1. JDK的下载、安装与配置

    一.JDK的下载 1.JDK下载地址:https://www.oracle.com/cn/java/technologies/javase-downloads.html 2.登录Oralce官网:ht ...

  2. PHP题库1

    选择题11. php中,不等运算符是( B.C ) A ≠    B !=   C <>   D >< 2. 函数的参数传递包括:( A.B ) A 按值传递       B ...

  3. python面试题总结

    Python语言特性 1. Python的函数参数传递 ​ 看两个如下例子,分析运行结果 #代码1 a = 1 def fun(a): a = 2 fun(a) print(a) #1 #代码2 a ...

  4. hibernate 中持久化标识 OID

    OID 全称是 Object Identifier,又叫做对象标识符 是 hibernate 用于区分两个对象是否是同一个对象的标识的方法 标识符的作用:可以让 hibernate 来区分多个对象是否 ...

  5. C#开发BIMFACE系列35 服务端API之模型对比6:获取模型构建对比分类树

    系列目录     [已更新最新开发文章,点击查看详细] BIMFACE平台提供了服务端"获取模型对比构件分类树"API.目录树返回结果以树状层级关系显示了增删改的构件信息,里面无法 ...

  6. CentOS7.8搭建STF

    安装命令插件(rz.sz): yum install -y lrzsz wget unzip zip编辑配置文件导致命令无法使用时:export PATH=/usr/local/sbin:/usr/l ...

  7. python-@函数装饰器

    例如@classmethod,@staticmethod的本质就是函数装饰器,其中,classmethod和staticmethod都是python的内置函数 使用@引用已有的函数后,可用于修饰其他函 ...

  8. python学习9 函数的基础知识

    1.函数的定义 def  func(): 2.函数的调用 func() 3.函数的返回值 #1.没有返回值 # (1)不写return # (2)只写return后面的代码不在继续执行,返回空,代表结 ...

  9. 前端 | JS 任务和微任务:promise 的回调和 setTimeout 的回调到底谁先执行?

    首先提一个小问题:运行下面这段 JS 代码后控制台的输出是什么? console.log("script start"); setTimeout(function () { con ...

  10. redis setNx原子锁

    https://github.com/suqi/rlock/blob/master/rlock.py 保持逻辑并发情况不产生多次结果 常用于下单,钱包,抢购,秒杀等场景 1 LOCK_TIMEOUT ...