hdu 4419 线段树 扫描线 离散化 矩形面积
//离散化 + 扫描线 + 线段树
//这个线段树跟平常不太一样的地方在于记录了区间两个信息,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 线段树 扫描线 离散化 矩形面积的更多相关文章
- POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]
题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...
- hdu1542 线段树扫描线求矩形面积的并
题意: 给你n个正方形,求出他们的所占面积有多大,重叠的部分只能算一次. 思路: 自己的第一道线段树扫描线题目,至于扫描线,最近会写一个总结,现在就不直接在这里写了,说下我的方 ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 1542"Atlantis"(线段树+扫描线求矩形面积并)
传送门 •题意 给你 n 矩形,每个矩形给出你 $(x_1,y_1),(x_2,y_2)$ 分别表示这个矩形的左下角和右上角坐标: 让你求这 n 个矩形并的面积: 其中 $x \leq 10^{5} ...
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU Atlantis 线段树 表达区间 矩形面积相交
http://acm.hdu.edu.cn/showproblem.php?pid=1542 我的做法是把x轴的表示为线段,然后更新y 不考虑什么优化的话,开始的时候,把他们表达成线段,并按y排序,然 ...
- hdu 1255(线段树 扫描线) 覆盖的面积
http://acm.hdu.edu.cn/showproblem.php?pid=1255 典型线段树辅助扫描线,顾名思义扫描线就是相当于yy出一条直线从左到右(也可以从上到下)扫描过去,此时先将所 ...
- 2015 UESTC 数据结构专题E题 秋实大哥与家 线段树扫描线求矩形面积交
E - 秋实大哥与家 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/contest/show/59 De ...
- hdu1828 线段树扫描线求矩形面积的周长
题意: 给你n个矩形,问你这n个矩形所围成的图形的周长是多少. 思路: 线段树的扫描线简单应用,这个题目我用的方法比较笨,就是扫描两次,上下扫描,求出多边形的上下边长和,然后同 ...
随机推荐
- cocos2d-之音乐背景播放
1.先加入头文件 #include <SimpleAudioEngine.h> using namespace CocosDenshion;//为了方便以下的函数使用,使用命名空间 2.在 ...
- perl学习笔记——文件测试
文件测试主要用于查看如文件是否存在.文件大小.文件更新时间等信息. 文件测试操作符 -e 测试文件是否存在: die "Oops!A file called '$filename' alr ...
- vue - path
//path用来处理路径问题的. 1 const from = path.join(_dirname, './appes6/js'); => d:/Users/xxchi/Desktop/ES6 ...
- python基础语法(一)
Python的特点 1. 简单 Python是一种代表简单思想的语言. 2. 易学 Python有极其简单的语法. 3. 免费.开源 Python是FLOSS(自由/开放源码软件)之一. 4. 高层语 ...
- 1364:Field 'sex' doesn't have a default value [ SQL语句 ]
1364:Field 'sex' doesn't have a default value [ SQL语句 ] 错误解决方法: 关闭MySQL的strict mode的具体做法: 找到MySQL目 ...
- 【Python 数据分析】pandas模块
上一节,我们已经安装了numpy,基于numpy,我们继续来看下pandas pandas用于做数据分析与数据挖掘 pandas安装 使用命令 pip install pandas 出现上图表示安装成 ...
- 用.net installshield打包程序时注册第三方控件
制作打包程序时如果用到外部控件需要按以下方式操作: 1.将控件及控件所用到的所有DLL加入打包程序. 2.将控件的Register由vsdrfDoNotRegister改为vsdrfCOMSelfRe ...
- Unity插件之NGUI学习(4)—— 创建UI2DSprite动画
创建一个新的Scene.并按 Unity插件之NGUI学习(2)创建UI Root,并在UI Root的Camera下创建一个Panel. 然后在选中Panel,在菜单中选择NGUI->Crea ...
- java序列化,二进制和数据流
类的序列化需要支持Serializable接口,如果类支持序列化,可以通过ObjectOutPutStream和ObjectInputStream将对象和Stream之间进行方便的转换. 首先来 看一 ...
- Python调用zabbix API批量添加主机 (读取Excel)
本文转载自:http://blog.mreald.com/178 Zabbix可以通过自发现添加主机,不过有时候不准确,通过API添加会更加准确! 脚本使用的跟zabbix相关的内容.参考的是zabb ...