思路:

以y的值进行离散化

根据x的值 对每一条y轴边进行处理,如果是"左边"则插入,是"右边"则删除。

  1. /*
  2. 扫描线+线段树+离散化
  3. 求多个矩形的周长
  4. */
  5. #include<stdio.h>
  6. #include<string.h>
  7. #include<stdlib.h>
  8. #include<algorithm>
  9. #include<iostream>
  10. #include<queue>
  11. #include<stack>
  12. #include<math.h>
  13. #include<map>
  14. using namespace std;
  15. const int maxn = ;
  16. const int maxm = ;
  17. struct SegTree{
  18. int l,r;
  19. int len;//区间代表的长度
  20. int segnum;//区间被分成的段数
  21. int cover;//区间被覆盖的次数
  22. int sum;//区间被覆盖的总长度
  23. bool lcover,rcover;
  24. }ST[ maxm<< ];
  25. struct Line{
  26. int st,ed,x;//竖边的两个y值
  27. bool InOut;//是否为左边
  28. bool operator < (Line L) const{
  29. return x<L.x;
  30. }
  31. };
  32.  
  33. Line yLine[ maxm ];
  34. int yIndex[ maxm ];
  35. int n;
  36.  
  37. void build( int L,int R,int n ){
  38. ST[ n ].l = L;
  39. ST[ n ].r = R;
  40. ST[ n ].len = yIndex[ R ]-yIndex[ L ];
  41. ST[ n ].sum = ST[ n ].cover = ST[ n ].segnum = ;
  42. ST[ n ].lcover = ST[ n ].rcover = false;
  43. if( R-L> ){
  44. int mid = (L+R)/;
  45. build( L,mid,*n );
  46. build( mid,R,*n+ );
  47. }
  48. return ;
  49. }
  50.  
  51. void Update_Len( int n ){
  52. if( ST[n].cover> ){
  53. ST[n].sum = ST[n].len;
  54. }
  55. else if( ST[n].r-ST[n].l> ){
  56. ST[n].sum = ST[*n].sum+ST[*n+].sum;
  57. }
  58. else
  59. ST[n].sum = ;
  60. }
  61.  
  62. void Update_Segnum( int n ){
  63. if( ST[n].cover> ){
  64. ST[n].lcover = ST[n].rcover = true;
  65. ST[n].segnum = ;
  66. }
  67. else if( ST[n].r-ST[n].l> ){
  68. ST[n].lcover = ST[*n].lcover;
  69. ST[n].rcover = ST[*n+].rcover;
  70. ST[n].segnum = ST[*n].segnum+ST[*n+].segnum-ST[*n].rcover*ST[*n+].lcover;
  71. }
  72. else{
  73. ST[n].segnum = ;
  74. ST[n].lcover = ST[n].rcover = false;
  75. }
  76. }
  77.  
  78. void PushUp ( int n ){
  79. Update_Len( n );//求节点包含的线段总长度
  80. Update_Segnum( n );
  81. }
  82.  
  83. void Insert( int left,int right,int n ){
  84. if( ST[ n ].l==left&&ST[ n ].r==right ){
  85. ST[ n ].cover++;
  86. }
  87. else {
  88. int mid = (ST[ n ].l+ST[ n ].r)/;
  89. if( right<=mid )
  90. Insert( left,right,*n );
  91. else if( left>=mid )
  92. Insert( left,right,*n+ );
  93. else{
  94. Insert( left,mid,*n );
  95. Insert( mid,right,*n+ );
  96. }
  97. }
  98. PushUp( n );
  99. }
  100.  
  101. void Delete( int left,int right,int n ){//删除矩形的右边
  102. if( ST[ n ].l==left&&ST[ n ].r==right ){
  103. ST[ n ].cover--;
  104. }
  105. else {
  106. int mid = (ST[ n ].l+ST[ n ].r)/;
  107. if( right<=mid )
  108. Delete( left,right,*n );
  109. else if( left>=mid )
  110. Delete( left,right,*n+ );
  111. else{
  112. Delete( left,mid,*n );
  113. Delete( mid,right,*n+ );
  114. }
  115. }
  116. PushUp( n );
  117. }
  118.  
  119. int GetIndex( int value ,int cnt ){
  120. return lower_bound(yIndex,yIndex+cnt,value )-yIndex;
  121. }
  122.  
  123. int main(){
  124. while( scanf("%d",&n)== ){
  125. int cnt = ;
  126. int x1,y1,x2,y2;
  127. for( int i=;i<n;i++ ){
  128. scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
  129. yLine[ *i ].x = x1;
  130. yLine[ *i+ ].x = x2;
  131. yLine[ *i ].st = yLine[ *i+ ].st = y1;
  132. yLine[ *i ].ed = yLine[ *i+ ].ed = y2;
  133. yLine[ *i ].InOut = true;
  134. yLine[ *i+ ].InOut = false;
  135. yIndex[ *i ] = y1;
  136. yIndex[ *i+ ] = y2;
  137. }
  138. sort( yIndex,yIndex+*n );
  139. sort( yLine,yLine+*n );
  140. for( int i=;i<*n;i++ ){
  141. if( yIndex[i]!=yIndex[i-] )
  142. yIndex[cnt++] = yIndex[i-];
  143. }
  144. yIndex[cnt++] = yIndex[*n-];
  145. build( ,cnt-, );
  146. int Ans = ;
  147. int PreSum = ;;//上一次记录的长度
  148. for( int i=;i<*n-;i++ ){
  149. if( yLine[i].InOut ){
  150. Insert( GetIndex(yLine[i].st,cnt),GetIndex(yLine[i].ed,cnt), );
  151. }
  152. else{
  153. Delete( GetIndex(yLine[i].st,cnt),GetIndex(yLine[i].ed,cnt), );
  154. }
  155. Ans += ST[].segnum**(yLine[i+].x-yLine[i].x);
  156. Ans += abs(ST[].sum-PreSum);
  157. PreSum = ST[].sum;
  158. }
  159. Delete( GetIndex(yLine[*n-].st,cnt),GetIndex(yLine[*n-].ed,cnt), );
  160. //特殊处理最后一条出边,因为没有下一条竖边了
  161. Ans += abs(ST[].sum-PreSum);
  162. printf("%d\n",Ans);
  163. }
  164. return ;
  165. }

POJ1177+线段树+扫描线的更多相关文章

  1. 【学习笔记】线段树—扫描线补充 (IC_QQQ)

    [学习笔记]线段树-扫描线补充 (IC_QQQ) (感谢 \(IC\)_\(QQQ\) 大佬授以本内容的著作权.此人超然于世外,仅有 \(Luogu\) 账号 尚可膜拜) [学习笔记]线段树详解(全) ...

  2. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  3. Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)

    题目链接:http://codeforces.com/contest/522/problem/D 题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...

  4. 【POJ-2482】Stars in your window 线段树 + 扫描线

    Stars in Your Window Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11706   Accepted:  ...

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

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

  6. BZOJ-3228 棋盘控制 线段树+扫描线+鬼畜毒瘤

    3228: [Sdoi2008]棋盘控制 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 23 Solved: 9 [Submit][Status][D ...

  7. BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞

    看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...

  8. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  9. POJ1151+线段树+扫描线

    /* 线段树+扫描线+离散化 求多个矩形的面积 */ #include<stdio.h> #include<string.h> #include<stdlib.h> ...

随机推荐

  1. C#根据WSDL文件生成WebService服务端代码

    转自:http://www.cnblogs.com/liyi93/archive/2012/01/30/2332320.html 虽然现在已经进入了.NET FrameWork 4.0的时代,WebS ...

  2. SharePoint2013 SharePoint-Hosted 模式 分页方法

    /**分页js插件 var ListPager = new listPaging(); 先调用start方法加载上下文 然后调用dataLoad方法查询第一页数据 需要设置几个属性值 ListPage ...

  3. Mysql数据库的索引原理

    写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...

  4. 认识JSON

    JSON 全称 JavaScript Object Notation,意思是JavaScript对象表示法.是一种基于文本的.独立于语言的轻量级数据交换格式.易于阅读和编写,易于机器解析和生成. 一. ...

  5. SQLSERVER2012用户登录error40

    昨天晚上公司停电了,电脑非正常关闭,今早回来之后,用sa登录sqlserver,一直报error40这个错,以前没碰到过,所以很紧张,问东问西,在网上也搜了好多,也跟着配置了好多,都不行,快被逼疯的时 ...

  6. 利用sys.dm_db_index_physical_stats查看索引碎片等数据(转)

    我们都知道,提高sql server的数据查询速度,最有效的方法,就是为表创建索引,而索引在对数据进行新增,删除,修改的时候,会产生索引碎片,索引碎片多了,就需要重新组织或重新生成索引,以达到索引的最 ...

  7. 鼠标点击input时,placeholder中的提示信息消失

    html代码: <input type="text" placeholder="多个关键词空格隔开"> 鼠标点击input时,placeholder ...

  8. TextView实现跑马灯效果

    网上有很多跑马灯的介绍,有很多跑马灯的代码.或许我的不是最好的,但是应该很容易明白的. 我们先来介绍一个跑马灯的代码 <LinearLayout xmlns:android="http ...

  9. linq递归

    public class Comment { public int Id { get; set; } public int ParentId { get; set; } public string T ...

  10. linux中的sticky bit

    今天看到有个目录的权限是rwxrwxrwt 很惊讶这个t是什么,怎么不是x或者-呢?搜了下发现: 这个t代表是所谓的sticky bit. sticky bit: 该位可以理解为防删除位. 一个文件是 ...