题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419

题目大意:给你n个矩形,每个矩形都有一种颜色,矩形覆盖会出现另外一种颜色,问你所有矩形中不同的颜色各出现的面积。

解题思路:开始一直只用一个标记,1,2,4,处理来处理去发现一直搞不来。最后用两个标记,一个存+1,-1,和普通面积并类似,另外开一个三位的标记数组,0位表示'R',1位表示‘G’,2位表示‘B’,sum数组要开8个状态(和8颗线段树思想类似),每次处理到当前节点时,该节点所有sum值清0(叶子节点的sum[u][0]表示的就是区间长度,要进行预先建树),根据自己当前的状态再由孩子传递数值上来进行更新操作。这题很巧妙的用到了或运算,表示我开始没想到,发散性思维 O.O。

 #include <iostream>
 #include <cstdio>
 #include <cstring>
 #include <algorithm>
 using namespace std;

 #define lz 2*u,l,mid
 #define rz 2*u+1,mid+1,r
 typedef long long lld;
 ;
 lld sum[*maxn][];
 *maxn][];
 int X[maxn];
 lld ans[];

 struct Node
 {
     int lx, rx, y;
     int c, s;
     Node() {};
     Node(int lx_, int rx_, int y_, int c_, int s_)
     {
         lx=lx_, rx=rx_, y=y_, c=c_, s=s_;
     }
     bool operator <(const Node &S) const
     {
         if(y==S.y) return s>S.s;
         else return y<S.y;
     }
 } line[maxn];

 int find(int tmp, int n)
 {
     , r=n, mid;
     while(l<=r)
     {
         mid=(l+r)>>;
         if(X[mid]==tmp) return mid;
         ;
         ;
     }
 }

 void push_up(int u, int l, int r)
 {
     ;
     ; i<=; i++) <<i);
     memset(sum[u],,sizeof(sum[u]));
     ]-X[l];
     else
     {
         ; i<; i++)
             sum[u][state|i]+=sum[*u][i]+sum[*u+][i];
     }
 }

 void build(int u, int l, int r)
 {
     memset(sum[u],,sizeof(sum[u]));
     memset(flag[u],,sizeof(flag[u]));
     if(l==r)
     {
         sum[u][]=X[r+]-X[l];
         return ;
     }
     ;
     build(lz);
     build(rz);
     sum[u][]=sum[*u][]+sum[*u+][];
 }

 void Update(int u, int l, int r, int tl, int tr, int s, int c)
 {
     if(tl>tr) return ;
     if(tl<=l&&r<=tr)
     {
         flag[u][s]+=c;
         push_up(u,l,r);
         return ;
     }
     ;
     if(tr<=mid) Update(lz,tl,tr,s,c);
     else if(tl>mid) Update(rz,tl,tr,s,c);
     else
     {
         Update(lz,tl,mid,s,c);
         Update(rz,mid+,tr,s,c);
     }
     push_up(u,l,r);
 }

 int main()
 {
     ;
     cin >> T;
     while(T--)
     {
         cin >> n;
         ;
         memset(flag,,sizeof(flag));
         memset(sum,,sizeof(sum));
         memset(ans,,sizeof(ans));
         ; i<n; i++)
         {
             int x1,x2,y1,y2, s;
             ];
             scanf("%s%d%d%d%d",ch,&x1,&y1,&x2,&y2);
             ]==;
             ]==;
             ;
             line[++num]=Node(x1,x2,y1,s,);
             X[num]=x1;
             line[++num]=Node(x1,x2,y2,s,-);
             X[num]=x2;
         }
         sort(X+,X+num+);
         sort(line+,line+num+);
         ;
         ; i<=num; i++)
             ]) X[++k]=X[i];
         build(,,k);
         ; i<num; i++)
         {
             int l=find(line[i].lx,k);
             ;
             Update(,,k,l,r,line[i].c,line[i].s);
             ; j<=; j++)
                 ans[j]+=sum[][j]*(line[i+].y-line[i].y);
         }
         printf("Case %d:\n",++tcase);
         swap(ans[],ans[]);
         ; i<=; i++)  cout << ans[i] <<endl;
     }
     ;
 }

【HDU4419 Colourful Rectangle】 线段树面积并的更多相关文章

  1. HDU-4419 Colourful Rectangle 矩形多面积并

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 利用二进制,R为1.G为2.B为4,然后通过异或运算可以得到其它组合颜色.建立7颗线段树,每颗线 ...

  2. hdu4419 Colourful Rectangle 12年杭州网络赛 扫描线+线段树

    题意:给定n个矩形,每个矩形有一种颜色,RGB中的一种.相交的部分可能为RG,RB,GB,RGB,问这n个矩形覆盖的面积中,7种颜色的面积分别为多少 思路:把x轴离散化做扫描线,线段树维护一个扫描区间 ...

  3. hdu 1255 覆盖的面积(线段树 面积 交) (待整理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积.   In ...

  4. POJ 1542 Atlantis(线段树 面积 并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 参考网址:http://blog.csdn.net/sunmenggmail/article/d ...

  5. [HDU 4419] Colourful Rectangle (扫描线 矩形面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积. 矩形面积并的扫描线维护的是长度,这道题 ...

  6. 线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)

    转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnl ...

  7. HDU 4419 Colourful Rectangle --离散化+线段树扫描线

    题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...

  8. 扫描线 + 线段树 : 求矩形面积的并 ---- hnu : 12884 Area Coverage

    Area Coverage Time Limit: 10000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit user ...

  9. 【HDU 1542】Atlantis(线段树+离散化,矩形面积并)

    求矩形面积并,离散化加线段树. 扫描线法: 用平行x轴的直线扫,每次ans+=(下一个高度-当前高度)*当前覆盖的宽度. #include<algorithm> #include<c ...

随机推荐

  1. 最适合作为Java基础面试题之Singleton模式

    看似只是最简单的一种设计模式,可细细挖掘,static.synchronized.volatile关键字.内部类.对象克隆.序列化.枚举类型.反射和类加载机制等基础却又不易理解透彻的Java知识纷纷呼 ...

  2. Linux命令 -- 查看系统版本的各种方法

    适用于CentOS

  3. MySQL:索引工作原理

    索引查找:通过索引键找到索引的叶子节点,再通过叶子节点的标记快速找到表中对应的行数据,再返回指定的列 索引找查是通过索引键定先位到一块局部区域,再开始扫描匹配的数据的. 为什么需要索引(Why is ...

  4. ionic实现上拉到底内容提示

    <!--html代码--> <ion-content has-bouncing = true on-drag-up="scrollDragUp()"> &l ...

  5. mysql ALL_O_DIRECT引发的unaligned AIO/DIO导致hang

    公司内部有一套mysql环境,使用的是percona server分支(和其他几十套环境的版本.参数完全相同),就这套环境每隔两三天就会hang一次,关键hang的时候服务器cpu也就是百分之三四十, ...

  6. Visual Studio添加dll程序集引用操作步骤

    Visual Studio 中添加引用的操作: 在“解决方案资源管理器”中,先右击项目图标,在弹出菜单选择“添加引用...” 然后在弹出的窗口中选择所要添加的选项,点击确定就可以了. 原文:http: ...

  7. Android listview下拉刷新 SwipeRefreshLayout

    今天在Google+上看到了SwipeRefreshLayout这个名词,遂搜索了下,发现竟然是刚刚google更新sdk新增加的一个widget,于是赶紧抢先体验学习下. SwipeRefreshL ...

  8. windows python 打印utf-8乱码

    从网上抓了一些字节流,想打印出来结果发生了一下错误: UnicodeEncodeError: 'gbk' codec can't encode character '\xbb' in position ...

  9. Android核心分析之十九电话系统之GSMCallTacker

    GSMCallTracker在本质上是一个Handler.<IGNORE_JS_OP> 1.jpg (1.52 KB, 下载次数: 1) 下载附件  保存到相册 2012-3-22 11: ...

  10. JQuery Mobile实现手机新闻浏览器(2)

    在上一篇文章中,已经讨论了程序的结构和页面的布局,并简单介绍了一些jQuery Mobile的使用技巧.在本篇文章中,笔者将继续完成我们web应用的新闻浏览器的设计. 程序的启动 我们现在来研究一下程 ...