hdu4419 Colourful Rectangle 12年杭州网络赛 扫描线+线段树
题意:给定n个矩形,每个矩形有一种颜色,RGB中的一种。相交的部分可能为RG,RB,GB,RGB,问这n个矩形覆盖的面积中,7种颜色的面积分别为多少
思路:把x轴离散化做扫描线,线段树维护一个扫描区间竖直方向上的各种颜色的长度
刚开始想着直接维护每段区间上7种颜色的长,但是写到删除的时候发现没办法删除,
然后想了半天,发现:需要的只是整个区间的颜色长度信息,所以,对于颜色更新来说,不需要往下传标记,只需要维护上push_up就好了
所以添加删除就简单多了。
用 1 2 4 分别代表R G B 然后RG RB GB RGB 分别为3 5 6 7
没有颜色用0来表示
线段树每个节点记录下R,G,B 分别被覆盖了几次。
往上更新的时候只需要考虑左右儿子的线段覆盖了父亲的颜色后总的区间各个颜色长度为多少即可,注意单个长度的情况。
一直卡在64位类型的转化上,全都换成64位的不对,最后强制转化才对的。。
// 略长,但是比较可看,
/// R:1 G:2 B:4
int hash[];
struct scanline
{
int x,y1,y2;
int col;
int flag ;
void set(int _x,int _y1,int _y2,int _col ,int _flag)
{
x = _x ;
y1 = _y1 ;
y2 = _y2 ;
col = _col ;
flag = _flag ;
}
};
bool cmp(scanline t1, scanline t2)
{
if(t1.x != t2.x)return t1.x < t2.x;
return t1.flag > t2.flag;
}
scanline sc[maxn * ];
int y[maxn * ];
int num;
struct node
{
int l,r;
int ml,mr;
int c1,c2,c4;
int l1[];
int mid()
{
return (l + r) /;
}
int len()
{
return mr - ml;
}
};
long long area[];
node tt[maxn * * ];
int nn ;
void init(int root )
{
memset(tt[root].l1,,sizeof(tt[root].l1));
tt[root].c1 = tt[root].c2 = tt[root].c4 = ;
}
void update1(int root )
{
// printf("root = %d\n",root);
int col = ;
if(tt[root].c1 > ) col = col|;
if(tt[root].c2 > ) col = col|;
if(tt[root].c4 > ) col = col|;
//printf("update1: col = %d\n",col);
memset(tt[root].l1,,sizeof(tt[root].l1));
if(tt[root].r - tt[root].l == )
{
tt[root].l1[col] = tt[root].len();
}
else if(col == )
{
for(int i = ;i < ;i ++ )
tt[root].l1[i] = tt[root*].l1[i] + tt[root*+].l1[i];
}
else if(col != )
{
for(int i = ; i < ; i ++ )
tt[root].l1[i|col] += (tt[root*].l1[i] + tt[root*+].l1[i]);
} return ;
}
void build(int root ,int l,int r )
{
tt[root].l = l ;
tt[root].r = r;
tt[root].ml = y[l-];
tt[root].mr = y[r-];
init(root);
tt[root].l1[] = tt[root].len();
if( l + >= r ) return ;
int mid = tt[root].mid();
build(root * , l , mid );
build(root * + , mid , r);
return ;
}
void upd(int root ,int l,int r ,int col,int val )
{
if(l <= tt[root].ml && tt[root].mr <= r)
{
if(col == ) tt[root].c1 += val ;
else if(col == ) tt[root].c2 += val ;
else if(col == ) tt[root].c4 += val ;
update1(root);
return ;
}
if(r <= tt[root * ].mr )
upd(root * , l,r,col,val);
else if(l >= tt[root * + ].ml )
upd(root * + , l,r ,col,val);
else
{
upd(root * ,l,r,col,val);
upd(root * + ,l,r,col,val);
}
update1(root);
}
int main()
{
int x1,x2,y1,y2;
memset(hash,,sizeof(hash));
hash['R'] = ;
hash['G'] = ;
hash['B'] = ;
int cas,ccc;
ccc = ;
char str[];
scanf("%d",&cas);
int n ;
while(cas -- )
{
num = ;
scanf("%d",&n);
for(int i = ; i <= n ; i++ )
{
scanf("%s %d %d %d %d",str,&x1,&y1,&x2,&y2);
y[num] = y1 ;
num ++ ;
sc[num].set(x1,y1,y2,hash[str[]],); y[num] = y2 ;
num ++ ;
sc[num].set(x2,y1,y2,hash[str[]],-);
}
int n1;
n1 = num ;
sort(y ,y + num);
nn = unique(y , y + num) - y;
build(,,nn);
sort(sc + , sc + n1 + ,cmp);
memset(area,,sizeof(area));
int i ;
i = ;
while(i <= n1 )
{
int j = i ;
while(sc[j].x == sc[i].x && j <= n1 )
{
upd(,sc[j].y1,sc[j].y2,sc[j].col,sc[j].flag);
j ++ ;
}
int len ;
if(j == n1 + ) len = ;
else len = sc[j].x - sc[i].x;
update1();
for(int k = ; k < ; k ++ )
area[k] = area[k] + (long long)(tt[].l1[k]) * (long long)(len) ;
i = j ;
}
printf("Case %d:\n",++ccc);
printf("%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d\n",area[],area[],area[],area[],area[],area[],area[]);
///cout<<area[1]<<endl<<area[2]<<endl<<area[4]<<endl<<area[3]<<endl<<area[5]<<endl<<area[6]<<endl<<area[7]<<endl;
}
return ;
}
hdu4419
hdu4419 Colourful Rectangle 12年杭州网络赛 扫描线+线段树的更多相关文章
- hdu 4046 2011北京赛区网络赛G 线段树 ***
还带这么做的,卧槽,15分钟就被A了的题,居然没搞出来 若某位是1,则前两个为wb,这位就是w #include<cstdio> #include<cstring> #defi ...
- hdu 4027 2011上海赛区网络赛G 线段树 成段平方根 ***
不能直接使用成段增减的那种,因为一段和的平方根不等于平方根的和,直接记录是否为1,是1就不需要更新了 #include<cstdio> #include<iostream> # ...
- HDU 5875 Function (2016年大连网络赛 H 线段树+gcd)
很简单的一个题的,结果后台数据有误,自己又太傻卡了3个小时... 题意:给你一串数a再给你一些区间(lef,rig),求出a[lef]%a[lef+1]...%a[rig] 题解:我们可以发现数字a对 ...
- 19徐州网络赛E 线段树加离散化
题目链接:https://nanti.jisuanke.com/t/41387 按wi的值建立权值线段树维护值为wi出现的最后位置,对于第i个人的答案,查询线段树[wi+m,max]区间的最大位置po ...
- HDU 4741 Save Labman No.004 (2013杭州网络赛1004题,求三维空间异面直线的距离及最近点)
Save Labman No.004 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Other ...
- HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)
Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU 4745 Two Rabbits (2013杭州网络赛1008,最长回文子串)
Two Rabbits Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Tota ...
- HDU 4747 Mex (2013杭州网络赛1010题,线段树)
Mex Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- HDU 4739 Zhuge Liang's Mines (2013杭州网络赛1002题)
Zhuge Liang's Mines Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
随机推荐
- malloc功能具体解释
一.原型:extern void *malloc(unsigned int num_bytes); 头文件:#include <malloc.h> 或 #include <alloc ...
- [转载] 树莓派读取温湿度传感器DHT11
原文地址: http://blog.csdn.net/liang890319/article/details/8739683 硬件: 树莓派 2.0 DHT模块 接树莓派5V GND GPIO1 功 ...
- Java OCR tesseract 图像智能字符识别技术 Java代码实现
接着上一篇OCR所说的,上一篇给大家介绍了tesseract 在命令行的简单用法,当然了要继承到我们的程序中,还是需要代码实现的,下面给大家分享下java实现的例子. 拿代码扫描上面的图片,然后输出结 ...
- QT 打开文件对话框汇总
Qstring fileName = QFileDialog::getOpenFileName(this, tr("open file"), " ", tr( ...
- SRM 590 DIV1
转载请注明出处,谢谢viewmode=contents">http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlov ...
- MyReport报表引擎2.0.0.0新功能
Web报表引擎:Web上的良好的打印解决方式,WinForm的打印预览体现,报表自己主动化,支持直接打印,页小计,统计,转成金额大写,一维码显示等功能,满足中国式报表的常见功能需求.Web报表编辑器: ...
- 玩转Web之servlet(一)---怎样创建一个servlet
Servlet概念:servlet就是用java编写的服务器端的小程序,用来完成下B/S架构(即浏览器和服务器架构)下客户端请求的响应处理. servlet通常在容器中运行Tomcat是常见的serv ...
- android--jenkins+gradle+android自动化构建apk步骤(转)
第一步,安装jenkins,这个网上教程挺多的. 第二步,下载并配置gradle.下载地址http://www.gradle.org/ 解压gradle至某路径下,如/usr/local/lib/gr ...
- 【IPC第二个进程间通信】管道Pipe
IPC进程间通信+管道Pipe IPC(Inter-Process Communication,进程间通信). 管道用于进程间共享数据,事实上质是共享内存 ...
- 【我们都爱Paul Hegarty】斯坦福大学IOS8公开组个人笔记28 ScrollView 幻灯片视图
随着移动设备,iphone屏幕尺寸的限制.超过内容的屏幕大小为scrollview于,通过滑动来获得.scrollview滑动方向可以是也可以是横向垂直,scrollview可以嵌套,例如,纵向滑动s ...