HDU 4419 Colourful Rectangle --离散化+线段树扫描线
题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积。
解法: 很容易想到线段树扫描线求矩形面积并,但是如何维护每种颜色的长度着实让我伤透了脑筋。后来看了一位朋友的题解,才幡然醒悟。
开始想到了用二进制表示颜色,R用001表示,G用010表示,B用100表示。那么就可以用十进制1~7表示7种不同颜色了。
维护 cov[rt][1~3] 表示此区间内3种原色各有多少个, Len[rt][i]表示每种颜色的长度。
重点是pushup的写法,详情见代码, 离散化什么还比较简单。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define lll __int64
using namespace std;
#define N 10107 lll Len[*N][];
int cov[*N][]; struct Line
{
int y1,y2,x;
int col;
}line[*N];
int yy[*N]; int cmp(Line ka,Line kb) { return ka.x < kb.x; } void pushup(int l,int r,int rt)
{
int state = ;
for(int i=;i<=;i++) if(cov[rt][i]) state |= (<<(i-)); //表示此区间内有的颜色
for(int i=;i<;i++) Len[rt][i] = ; //加了一层,要重新算各个颜色的长度
if(l+ == r) //叶子节点
{
Len[rt][state] = yy[r]-yy[l]; //只有此颜色state,长度为yy[r]-yy[l]
return;
}
for(int i=;i<;i++) //否则使用下面的更新
Len[rt][i|state] += Len[*rt][i] + Len[*rt+][i];
} void build(int l,int r,int rt)
{
for(int i=;i<=;i++) cov[rt][i] = ;
for(int i=;i<;i++) Len[rt][i] = ;
Len[rt][] = yy[r]-yy[l];
if(l == r-) return;
int mid = (l+r)/;
build(l,mid,*rt);
build(mid,r,*rt+);
} void update(int l,int r,int aa,int bb,int cover,int rt)
{
if(aa <= l && bb >= r)
{
if(cover > ) cov[rt][cover]++;
else cov[rt][-cover]--;
pushup(l,r,rt);
return;
}
if(l+ == r) return;
int mid = (l+r)/;
if(aa <= mid)
update(l,mid,aa,bb,cover,*rt);
if(bb > mid)
update(mid,r,aa,bb,cover,*rt+);
pushup(l,r,rt);
} int main()
{
int n,m,t,cs = ,i,j;
int x1,y1,x2,y2,c;
char ss[];
scanf("%d",&t);
while(t--)
{
m = ;
scanf("%d",&n);
for(i=;i<n;i++)
{
scanf("%s%d%d%d%d",ss,&x1,&y1,&x2,&y2);
if(ss[] == 'R') c = ;
else if(ss[] == 'G') c = ;
else c = ;
line[m].x = x1,line[m].y1 = y1,line[m].y2 = y2,line[m].col = c,yy[m++] = y1;
line[m].x = x2,line[m].y1 = y1,line[m].y2 = y2,line[m].col = -c,yy[m++] = y2;
}
m--;
sort(yy+,yy+m+);
int cnt = ;
for(i=;i<=m;i++)
{
if(yy[i] != yy[i-])
yy[cnt++] = yy[i];
}
cnt--;
build(,cnt,);
sort(line+,line+m+,cmp);
lll ans[];
memset(ans,,sizeof(ans));
printf("Case %d:\n",cs++);
for(i=;i<m;i++)
{
int L = lower_bound(yy+,yy+cnt+,line[i].y1)-yy;
int R = upper_bound(yy+,yy+cnt+,line[i].y2)-yy-;
update(,cnt,L,R,line[i].col,);
for(j=;j<;j++)
ans[j] += Len[][j]*(line[i+].x-line[i].x);
}
printf("%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n",ans[],ans[],ans[],ans[],ans[],ans[],ans[]);
}
return ;
}
HDU 4419 Colourful Rectangle --离散化+线段树扫描线的更多相关文章
- HDU 4419 Colourful Rectangle(线段树+扫描线)
题目链接 主要是pushup的代码,其他和区间更新+扫描线差不多. 那个区间如果要再刷一层x,那么sum[x][rt] = que[r+1] - que[l];但是如果原本有颜色为i,颜色将会变成i| ...
- HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)
版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...
- hdu 4419 Colourful Rectangle (离散化扫描线线段树)
Problem - 4419 题意不难,红绿蓝三种颜色覆盖在平面上,不同颜色的区域相交会产生新的颜色,求每一种颜色的面积大小. 比较明显,这题要从矩形面积并的方向出发.如果做过矩形面积并的题,用线段树 ...
- HDU 1255 覆盖的面积 (线段树+扫描线+离散化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意很清楚,就是让你求矩阵之间叠加层数大于1的矩形块的面积和. 因为n只有1000,所以我离散化 ...
- HDU 1542 矩形面积并【离散化+线段树+扫描线】
<题目链接> 题目大意: 给你n个矩形,求出它们面积的并. 解题分析: 此题主要用到了扫描线的思想,现将各个矩形的横坐标离散化,然后用它们离散化后的横坐标(相当于将矩形的每条竖线投影在x轴 ...
- 【HDU4419 Colourful Rectangle】 线段树面积并
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:给你n个矩形,每个矩形都有一种颜色,矩形覆盖会出现另外一种颜色,问你所有矩形中不同的颜 ...
- HDU1542-Atlantis【离散化&线段树&扫描线】个人认为很全面的详解
刚上大一的时候见过这种题,感觉好牛逼哇,这都能算 如今已经不打了,不过适当写写题保持思维活跃度还是不错的,又碰到这种题了,想把它弄出来 说实话,智商不够,看了很多解析,花了4.5个小时才弄明白 网上好 ...
- [HDU 4419] Colourful Rectangle (扫描线 矩形面积并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积. 矩形面积并的扫描线维护的是长度,这道题 ...
- HDU 3642 Get The Treasury (线段树扫描线,求体积并)
参考链接 : http://blog.csdn.net/zxy_snow/article/details/6870127 题意:给你n个立方体,求覆盖三次以上(包括三次)的区域的体积 思路:先将z坐标 ...
随机推荐
- git 使用笔记(一)
1. 环境介绍 windows10 2.使用 2.1 安装git for windows 2.2 创建一个文件夹, 开始git管理 2.3 查看该目录,包括隐藏文件 2.4 把testgit.txt添 ...
- 学习Scala: 初学者应该了解的知识
Scala开发参照清单 这里列出在开发一个Scala工程中需要参照的资料. 官网网站 http://www.scala-lang.org/ 文档网站 http://docs.scala-lang.or ...
- python爬虫——爬取NUS-WIDE数据库图片
实验室需要NUS-WIDE数据库中的原图,数据集的地址为http://lms.comp.nus.edu.sg/research/NUS-WIDE.htm 由于这个数据只给了每个图片的URL,所以需 ...
- Powerbuilder编写身份证校验码
public function boolean of_calc_cardid_verifycode (string as_cardid, ref string as_verifycode); /* 计 ...
- 【OpenCV & CUDA】OpenCV和Cuda结合编程
一.利用OpenCV中提供的GPU模块 目前,OpenCV中已提供了许多GPU函数,直接使用OpenCV提供的GPU模块,可以完成大部分图像处理的加速操作. 基本使用方法,请参考:http://www ...
- has_many :through VS has_and_belongs_to_many
user role has_and_belongs_to_many role.destroy: 关联表user_roles先删除记录,再role删除. has_many :through user. ...
- jQuery.merge()
jQuery.merge( first, second ) //返回Array 合并两个数组内容到第一个数组. first第一个用来合并的数组,元素是第二数组加进来的. second第二个数组合并到第 ...
- SharePoint 2013 对象模型操作"网站设置"菜单
在SharePoint的开发中,经常会有客户提到网站操作上的栏目过多,其实,我们除了可以通过Feature的方式添加,还可以通过服务器端对象模型的方式添加:下面,让我用简单的例子,给大家介绍一下: 1 ...
- Engine中如何实现先居中显示要素再闪烁
[解决办法]:需要在要素居中显示之后.闪烁之前执行IScreenDisplay.UpdateWindow强制全刷,如: //居中显示要素 IActiveView actView = axMapCont ...
- JAVA基础学习day15--集合二 TreeSet和泛型
一.TreeSet 1.1.TreeSet Set:hashSet:数据结构是哈希表.线程是非同步的. 保证元素唯一性的原理:判断元素的HashCode值是否相同. 如果 ...