//离散化 + 扫描线 + 线段树
//这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层。len[i]起传递儿子与父亲的关系,而num[i]不起传递作用,只是单纯的表示被覆盖的区间。
//然后就是pushUp函数,必须在update到底层后即更新num[]和len,然后把len传上去。
//离散化后由于求的是面积,所以我是把每条长度为1的线段当做一个点, 即把左端点表示此段长度。而不是把点当成点。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath> using namespace std;
#define lson l, m, rt<<1
#define rson m + 1, r, rt<<1|1
typedef long long ll;
const int maxn = 2e4 + ; struct Seg{
char c;
int y, s, t, tag;
}ss[maxn];
bool cmp(Seg a, Seg b){
return a.y < b.y;
}
int san[maxn], tot;
int num[maxn << ][],len[maxn << ][];
ll ans[];
void pushUp(int l, int r, int rt){
int state = (num[rt][] > ? : ) | (num[rt][] > ? : ) | (num[rt][] > ? : );
memset(len[rt], , sizeof(len[rt]));
if (state){
len[rt][state] = san[r] - san[l - ];
for (int i = ; i < ; ++i){
if (state != (state|i)){
int tmp = len[rt<<][i] + len[rt<<|][i];
len[rt][state|i] += tmp;
len[rt][state] -= tmp;
}
}
}
else if (l != r){
for (int i = ; i < ; ++i) len[rt][i] = len[rt<<][i] + len[rt<<|][i];
}
}
int getC(char c){
if (c == 'R') return ;
if (c == 'G') return ;
return ;
}
void update(int L, int R, char c, int tag, int l, int r, int rt){
if (L <= l && R >= r){
int cc = getC(c);
num[rt][cc] += tag;
//注意
pushUp(l, r, rt);
return ;
}
int m = (l + r) >> ;
if (L <= m) update(L, R, c, tag, lson);
if (R > m) update(L, R, c, tag, rson);
pushUp(l, r, rt);
}
int T, n;
int main(){
int tcas = ;
int x1, x2, y1, y2;
char s[];
scanf("%d", &T);
while (T--){
scanf("%d", &n);
tot = ;
for (int i = ; i <= n; ++i){
scanf("%s%d%d%d%d", s,&x1, &y1, &x2, &y2);
ss[i].c = s[]; ss[i].y = y1; ss[i].s = x1; ss[i].t = x2, ss[i].tag= ;
ss[i + n].c = s[]; ss[i + n].y = y2; ss[i + n].s = x1; ss[i + n].t = x2, ss[i + n].tag = -;
san[tot++] = x1 ; san[tot++] = x2;
}
n = n * ; sort(san, san + tot);
tot = unique(san, san + tot) - san;
sort(ss + , ss + n + , cmp);
ss[].y = ss[].y; memset(num, , sizeof(num));
memset(len, , sizeof(len));
memset(ans, , sizeof(ans));
for (int i = ; i <= n; ++i){
int l = lower_bound(san, san + tot, ss[i].s) - san + ;
int r = lower_bound(san, san + tot, ss[i].t) - san;
/*cout << " l = " << l << " r = " << r ;
cout << " tag = " << ss[i].tag << " c = "<< ss[i].c << endl;
for (int j = 1; j < 8; ++j) cout << len[1][j] << " ";
cout << endl;
cout << endl;
*/
if (ss[i].y != ss[i - ].y){
for (int j = ; j < ; ++j){
ans[j] += (ll)(ss[i].y - ss[i - ].y) * (ll)len[][j];
}
}
update(l, r, ss[i].c, ss[i].tag, , tot - , );
}
printf("Case %d:\n", ++tcas);
swap(ans[], ans[]);
for (int i = ; i < ; ++i)
printf("%lld\n", ans[i]);
}
return ;
}

hdu 4419 线段树 扫描线 离散化 矩形面积的更多相关文章

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

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

  2. hdu1542 线段树扫描线求矩形面积的并

    题意:       给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路:       自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...

  3. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  4. HDU 1542"Atlantis"(线段树+扫描线求矩形面积并)

    传送门 •题意 给你 n 矩形,每个矩形给出你 $(x_1,y_1),(x_2,y_2)$ 分别表示这个矩形的左下角和右上角坐标: 让你求这 n 个矩形并的面积: 其中 $x \leq 10^{5} ...

  5. hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  6. HDU Atlantis 线段树 表达区间 矩形面积相交

    http://acm.hdu.edu.cn/showproblem.php?pid=1542 我的做法是把x轴的表示为线段,然后更新y 不考虑什么优化的话,开始的时候,把他们表达成线段,并按y排序,然 ...

  7. hdu 1255(线段树 扫描线) 覆盖的面积

    http://acm.hdu.edu.cn/showproblem.php?pid=1255 典型线段树辅助扫描线,顾名思义扫描线就是相当于yy出一条直线从左到右(也可以从上到下)扫描过去,此时先将所 ...

  8. 2015 UESTC 数据结构专题E题 秋实大哥与家 线段树扫描线求矩形面积交

    E - 秋实大哥与家 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 De ...

  9. hdu1828 线段树扫描线求矩形面积的周长

    题意:       给你n个矩形,问你这n个矩形所围成的图形的周长是多少. 思路:       线段树的扫描线简单应用,这个题目我用的方法比较笨,就是扫描两次,上下扫描,求出多边形的上下边长和,然后同 ...

随机推荐

  1. java 入门-helloWorld

    Java 教程 Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言. Java可运行于多个平台,如Windows, Mac OS,及其他多种UNIX版本的系统. ...

  2. Androidproject师进阶之路 :《Android开发进阶:从小工到专家》上市啦!

    封面 文件夹1 文件夹2 - 当当购买链接 - 京东购买链接 为什么写这本书 写这本书的念头由来已久了. 或许是从我打算写<Android源代码设计模式解析与实战>那时起就萌生了这个念头, ...

  3. Django——Django中的QuerySet API 与ORM(对象关系映射)

    首先名词解释. ORM: 对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型 ...

  4. css样式布局中position的那些事儿

    哎,页面布局及设计开发.对于一个一直从事后台开发来说屌丝来说,确实是件非常费时.费力,非常艰难的一件事. 今晚是想实现把多张重叠在一起.或是标记一张图片中不同的位置然后赋以超链接.花了一晚上的时间,才 ...

  5. JUDE工具类图制作

    1. 类图图形元素 2. 连接线条 线的关系解释如下: 3. 创建一个类

  6. mongoDB 获取最后插入的文档的ObjectID/_id方法

    http://stackoverflow.com/questions/3338999/get-id-of-last-inserted-document-in-a-mongodb-w-java-driv ...

  7. 解析式/推导式, 生成器 datetime 内建函数

    列表解析式(List Comprehension) 语法: [返回值 for 元素 in 可迭代对象 if 条件] 使用中括号[],内部是for循环,if条件可选. 返回一个新的列表. 列表解析式的作 ...

  8. VS2017、netcore版本更新升级

    VS2017 剩下的就是下一步了. netcore 访问:https://www.microsoft.com/net/download/archives 找到对应版本(最新版本) 下载安装就可以了 装 ...

  9. mongodb 实现关系型数据库中查询某一列 的效果

    近期在tornado\mongodb\ansible mongodb中有个find()方法非常牛逼,能够将集合中全部的表都传出来,一開始我这么写 class Module_actionHandler( ...

  10. obj-fit

    该 object-fit CSS 属性指定替换元素的内容应该如何适应到其使用的高度和宽度确定的框. 初始值 fill 适用于 替换元素 遗传 是 媒体 视觉 计算值 按规定 动画类型 离散的 为了规范 ...