题意: 有三种颜色的矩形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 --离散化+线段树扫描线的更多相关文章

  1. HDU 4419 Colourful Rectangle(线段树+扫描线)

    题目链接 主要是pushup的代码,其他和区间更新+扫描线差不多. 那个区间如果要再刷一层x,那么sum[x][rt] = que[r+1] - que[l];但是如果原本有颜色为i,颜色将会变成i| ...

  2. HDU 1264 Counting Squares (线段树-扫描线-矩形面积并)

    版权声明:欢迎关注我的博客.本文为博主[炒饭君]原创文章,未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/25471349 P ...

  3. hdu 4419 Colourful Rectangle (离散化扫描线线段树)

    Problem - 4419 题意不难,红绿蓝三种颜色覆盖在平面上,不同颜色的区域相交会产生新的颜色,求每一种颜色的面积大小. 比较明显,这题要从矩形面积并的方向出发.如果做过矩形面积并的题,用线段树 ...

  4. HDU 1255 覆盖的面积 (线段树+扫描线+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意很清楚,就是让你求矩阵之间叠加层数大于1的矩形块的面积和. 因为n只有1000,所以我离散化 ...

  5. HDU 1542 矩形面积并【离散化+线段树+扫描线】

    <题目链接> 题目大意: 给你n个矩形,求出它们面积的并. 解题分析: 此题主要用到了扫描线的思想,现将各个矩形的横坐标离散化,然后用它们离散化后的横坐标(相当于将矩形的每条竖线投影在x轴 ...

  6. 【HDU4419 Colourful Rectangle】 线段树面积并

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:给你n个矩形,每个矩形都有一种颜色,矩形覆盖会出现另外一种颜色,问你所有矩形中不同的颜 ...

  7. HDU1542-Atlantis【离散化&线段树&扫描线】个人认为很全面的详解

    刚上大一的时候见过这种题,感觉好牛逼哇,这都能算 如今已经不打了,不过适当写写题保持思维活跃度还是不错的,又碰到这种题了,想把它弄出来 说实话,智商不够,看了很多解析,花了4.5个小时才弄明白 网上好 ...

  8. [HDU 4419] Colourful Rectangle (扫描线 矩形面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积. 矩形面积并的扫描线维护的是长度,这道题 ...

  9. HDU 3642 Get The Treasury (线段树扫描线,求体积并)

    参考链接 : http://blog.csdn.net/zxy_snow/article/details/6870127 题意:给你n个立方体,求覆盖三次以上(包括三次)的区域的体积 思路:先将z坐标 ...

随机推荐

  1. Python: Convert rst to html

    pip install sphinx rst2html.py in_file.rst out_file.html

  2. Hibernate中的脏检查和缓存清理机制

    脏检查 Session到底是如何进行脏检查的呢?当一个Customer对象被加入到Session缓存中时,Session会为Customer对象的值类型的属性复制一份快照.当Session清理缓存时, ...

  3. 小白初学ABP框架,着实累啊

    这几天在学习ABP相关的知识AutoMapper ,AngularJS,Less,DI(dependencyInjection),EntityFramework code first以及相关NuGet ...

  4. Ansible用于网络设备管理 part 2 对Jinja2 YAML 和 module的理解

    虽然很不想用“应该”这个词,但是还是写上了,的确我自己目前就是这么理解的. 那么这个理解就是,Ansible的一个key point 就是总的一个playbook是去依赖很多元素的,就像一开始那个图里 ...

  5. [js开源组件开发]js多选日期控件

    js多选日期控件 详情请见:http://www.lovewebgames.com/jsmodule/calendar.html 它的github地址:https://github.com/tianx ...

  6. gulp入坑系列(3)——创建多个gulp.task

    继续gulp的爬坑路,在准备get更多gulp的具体操作之前,先来明确一下在gulp中创建和使用多个task任务的情况. gulp所要做的操作都写在gulp.task()中,系统有一个默认的defau ...

  7. webservice 的wsdl文件生成客户端java类

    提供两个方法: 第一个: 发布webservice项目后, 地址栏地址  http://localhost:8888/lxitedu.webservice.cxf-ch2/services/userS ...

  8. 为网站添加ico图标

    1.将目标图片装换为.ico格式 在线转换工具:http://www.bitbug.net/ 2.将装换后的图标放入项目文件中,一般命名为favicon 3.在项目文件的index页面中引入 < ...

  9. C语言预处理命令之条件编译

    在C语言中,预处理指令是以#号开头的代码行.#号必须是该行除了任何空白字符外的第一个字符.#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符.整行语句构成了一条预处理指令,该指令将在编译器 ...

  10. C语言--static全局使用示例

    前言:看到很多使用Objective-C开发IOS的大牛,有时候会使用static全局变量,相比之下,我却很少用这个,从而很少对其有着比较有实质意义的理解,甚至更别说运用它了. 今天,经过一番思考和自 ...