题意:给定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年杭州网络赛 扫描线+线段树的更多相关文章

  1. hdu 4046 2011北京赛区网络赛G 线段树 ***

    还带这么做的,卧槽,15分钟就被A了的题,居然没搞出来 若某位是1,则前两个为wb,这位就是w #include<cstdio> #include<cstring> #defi ...

  2. hdu 4027 2011上海赛区网络赛G 线段树 成段平方根 ***

    不能直接使用成段增减的那种,因为一段和的平方根不等于平方根的和,直接记录是否为1,是1就不需要更新了 #include<cstdio> #include<iostream> # ...

  3. HDU 5875 Function (2016年大连网络赛 H 线段树+gcd)

    很简单的一个题的,结果后台数据有误,自己又太傻卡了3个小时... 题意:给你一串数a再给你一些区间(lef,rig),求出a[lef]%a[lef+1]...%a[rig] 题解:我们可以发现数字a对 ...

  4. 19徐州网络赛E 线段树加离散化

    题目链接:https://nanti.jisuanke.com/t/41387 按wi的值建立权值线段树维护值为wi出现的最后位置,对于第i个人的答案,查询线段树[wi+m,max]区间的最大位置po ...

  5. 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 ...

  6. HDU 4738 Caocao's Bridges (2013杭州网络赛1001题,连通图,求桥)

    Caocao's Bridges Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. HDU 4745 Two Rabbits (2013杭州网络赛1008,最长回文子串)

    Two Rabbits Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Tota ...

  8. HDU 4747 Mex (2013杭州网络赛1010题,线段树)

    Mex Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  9. 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 ...

随机推荐

  1. jenkins配置.net mvc网站

    jenkins配置.net mvc网站 上一篇使用jenkins配置.net mvc网站进行持续集成一只是简单介绍了jenkins构建站点到本地服务器,这一篇,就来讲解如何部署站点到指定的服务器上面. ...

  2. PM俱乐部之旅7-弱活着

     有些人认为,最终我们放松一点时间,有意想不到的事情发生--公司组织结构调整. 公司由于业务范围调整,所以要进行对应的组织结构调整.PMO部门也随之重组,项目经理俱乐部的活动改成项目交流会,请项目 ...

  3. [Windows Phone] 地图控制项的经纬度

    原文:[Windows Phone] 地图控制项的经纬度 前言 本文主要示范如何使用地图经纬度以及显示地标和行人街道,并透过卷轴控制地图缩放比例的功能. ? 实作 step1 建立专案. ? step ...

  4. PocketSphinx语音识别系统语言模型的训练和声学模型的改进

    PocketSphinx语音识别系统语言模型的训练和声学模型的改进 zouxy09@qq.com http://blog.csdn.net/zouxy09 关于语音识别的基础知识和sphinx的知识, ...

  5. AC自己主动机 总结

    模板--参考六如家培训指南 /*===============================*\ 依照训练指南写的 \*===============================*/ #incl ...

  6. 很多Python新手教程

    重要提示 这不是一个教程新手程序员准备,你担任很快编程,或者没有使用1至2程序设计语言,请移步!这是一些编程经验准备.它最出名Java或C,理解命令行,Shell等待.简而言之,面向老鸟的,让老鸟高速 ...

  7. ubuntu下安装wine

    直接在终端里面输入“sudo apt-get install wine”不要引号,即可安装wine.至于使用它,终端命令就是“wine ....”举个例子,你现在要运行魔兽, 然后你的魔兽的文件夹的位 ...

  8. 理解和运用javascript中的call及apply

    call是为了改变函数上下文context而存在的,换言之,就是改变函数内部this的指向.因为javascript存在[定义时上下文],[运行时上下文]及[上下文]是可以改变的.例如:var fun ...

  9. Entity Framework mvc Code First data migration

    1. Code First 可以先在代码里写好数据模型,自动生成DB.下一次启动的时候会根据__MigrationHistory判断 数据库是否和模型一致. 详情参考:http://blogs.msd ...

  10. Datatable转换为Json 然后,Json数据导入 js 档

    C#在里面Datatable转换为Json的5代码示例 /// <summary> /// Datatable转换为Json /// </summary> /// <pa ...