//离散化 + 扫描线 + 线段树
//这个线段树跟平常不太一样的地方在于记录了区间两个信息,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. 在线安装eclipse中html/jsp/xml editor插件 eclipseeditor

    1.打开eclipse中的help————>Install New Software 2.点击Add按钮,然后弹出一个框,第一个文本框可以随便写,第二个一定要写: http://download ...

  2. mysql增量备份(2/2)

    前言 这是在百度文库里看到的文章,原名叫做<MYSQL 完全与增量备份及恢复文档 >,是关于完全备份和增量备份以及恢复文档的...... 文档介绍 本文档采用 mysqldump  对数据 ...

  3. Win7如何改变用户文件夹位置

    现在装WIN7后第一件就是改变用户账户文件夹位置..因为里面存着一些软件的设定和信息等..不必要每次装后都手动改一次.. 已前用优化大师改.太麻烦.也不稳定有时有些目录不能完全改过来.. 通过命令mk ...

  4. 网络编程——C10K简述

    C10K问题   网络服务在处理数以万计的客户端连接时,往往出现效率底下甚至完全瘫痪,这被成为C10K问题. (C10K = connection 10 kilo 问题).k 表示 kilo,即 10 ...

  5. 获取取并下载tuku的漫画的爬虫

    代码地址如下:http://www.demodashi.com/demo/12842.html 概述 一个简单的爬虫,实现是爬取tuku网站的漫画.并下载到脚本的文件夹中,下载的漫画按照章节名放在各自 ...

  6. jrebel license server 激活方法

    方法1: 使用已经封装好的jar包,保持一直运行即可(放到服务器上). 链接:https://pan.baidu.com/s/1rrn-6F26JpD5RSsbJV3-hQ 密码: dscu 服务器上 ...

  7. Jpa调用存储过程及参数

    public List<Object> findAllEntityListBySearch(Long inputInfoId, int flag) throws Exception { L ...

  8. Android Camera 使用小结。两种方法:一是调用系统camera app,二是自己写camera程序。

    源文链接:http://www.cnblogs.com/franksunny/archive/2011/11/17/2252926.html Android Camera 使用小结 Android手机 ...

  9. css - 紧贴底部的页脚

    有的时候,由于页面长度不够,页面底部的页脚会很尴尬的跑上来,如图: 有的同学可能会想用position:fixed;bottom:0;来永远居底.但有些场景确实不适合. 这是我从YII2中找到的简单解 ...

  10. NPM的天坑: 解决ERR! code UNABLE_TO_VERIFY_LEAF_SIGNATURE

    各种下载失败,并不是镜像源的问题,哪怕切换淘宝源也无法下载.总之就像断网一般无法下载.无关网络. 解决方案: http://stackoverflow.com/questions/20747817/e ...