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坐标 ...
随机推荐
- LGLSearchBar
平时我们都是用UITextFeild 来写搜索框, 最近有时间就自己重新封装了UISearchBar, 他可以自行修改里面的属性来达到我们使用的要求. 源代码下载地址:https://github.c ...
- ASP.NET 5新特性
近期微软发布了ASP.NET 5.0,本次发布的新特性需求源于大量用户的反馈和需求,例如灵活的跨平台运行时和自主部署能力使ASP.NET应用不再受限于IIS.Cloud-ready环境配置降低了云端部 ...
- saltstack学习笔记1 --安装
salt官网:http://docs.saltstack.cn/zh_CN/latest/ 安装教程: - http://docs.saltstack.cn/zh_CN/latest/topics/i ...
- 一句命令快速合并 JS、CSS
在项目开发环境下,我们会把 JS 代码尽可能模块化,方便管理和修改,这就避免不了会出现一个项目自身 JS 文件数量达到 10 个或者更多. 而项目上线后,会要求将所有 JS 文件合并为 1 个或者几个 ...
- javascript --- 词法分析
JavaScript代码自上而下执行,但是在js代码执行前,会首先进行词法分析,所以事实上,js运行要分为词法分析和执行两个阶段. 词法分析主要分为三步: 第一步: 分析形参: 第二步: 分析变量声明 ...
- Create a “% Complete” Progress Bar with JS Link in SharePoint 2013
Create a “% Complete” Progress Bar with JS Link in SharePoint 2013 SharePoint 2013 has a lot new fea ...
- Sharepoint学习笔记—习题系列--70-573习题解析 -(Q51-Q53)
Question 51You use a third-party site definition to create SharePoint sites.You need to add a Web Pa ...
- 初识 TextKit
iOS 7 的发布给开发者的案头带来了很多新工具.其中一个就是 TextKit.TextKit 由许多新的 UIKit 类组成,顾名思义,这些类就是用来处理文本的.在这里,我们将介绍 TextKit ...
- NSString的八条实用技巧
NSString的八条实用技巧 有一篇文章写了:iOS开发之NSString的几条实用技巧 , 今天这篇,我们讲讲NSString的八条实用技巧.大家可以收藏起来,方便开发随时可以复制粘贴. 0.首字 ...
- 日常工作生活中的做人做事道理[持续更新ing]
1.凡是预则立,不预则废 2.不能用特殊案例说明事情本身的发展规律 3.任务不能拖,需主动出击,想方设法完成 4.工作要有细致化的沟通和安排 5.解决问题和安排任务可以逆向思维的去想 6.问题要举一反 ...