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坐标 ...
随机推荐
- Linux Shell系列教程之(十五) Shell函数简介
本文是Linux Shell系列教程的第(十五)篇,更多Linux Shell教程请看:Linux Shell系列教程 函数可以将一个复杂功能划分成若干模块,从而使程序结构更加清晰,代码重复利用率更高 ...
- abap number range
如有转载请注明出处:http://blog.csdn.net/donkey2004112103/archive/2009/04/13/4070996.aspx 1.sap numbe range在标准 ...
- ArcEngine尝试读取或写入受保护的内存
先说一下我的开发环境: Win10 + ArcGIS10.0 + ArcEngine10.0 + Framework4.0 今天调用新的GP工具则出现"尝试读取或写入受保护的内存.这通常指示 ...
- Add a file to a Document Library and update metadata properties in a single method添加文档的方法
private void AddFileToDocumentLibrary(string documentLibraryUrl, string filename, byte[] file_bytes, ...
- JSP--JavaBean
JSP 最强有力的一个方面就是能够使用 JavaBean 组件. 按照 Sun 公司的定义, JavaBean是一个可重复使用的软件组件.实际上 JavaBean 是一种 Java 类,通过封装属性和 ...
- date\"123456 错误排查
最近服务器重装,干脆将所有的源代码都重新整理了一下,开始一切正常,后来发现,每次修改一个画面的时候就会报错 跟踪了下发现是datetime.SmartDate等时间类型的数据,在进行序列化的时候改变了 ...
- [转]Linux下的Makefile
Makefile 介绍——————— make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序. 首先,我们用一个示例来说明Makefile的书写规则.以便 ...
- Jmeter调试工具---Debug Sampler
一.Debug Sampler介绍: 使用Jmeter开发脚本时,难免需要调试,这时可以使用Jmeter的Debug Sampler,它有三个选项:JMeter properties,JMeter v ...
- Java中关于WeakReference和WeakHashMap的理解
新美大的10月11日的笔试中有一道选择题,让选择函数返回结果,代码如下: private static String test(){ String a = new String("a&quo ...
- jquery.qrcode.js 插件生成二维码
下载地址:https://github.com/jeromeetienne/jquery-qrcode 例子: <!doctype html> <html> <head& ...