今天刚看到这个模板我是懵逼的,这个线段树既没有建树,也没有查询,只有一个update,而且区间成段更新也没有lazy标记....研究了一下午,我突然我发现我以前根本不懂扫描线,之所以没有lazy标记,是因为扫描线每次只查询1-n里的所有有值的区间长度,因为只要1-n,而不会查找到某些小区间,所以也就不用lazy,而且也无需查询,每次插入完只需要 知道sum[1]是多少即可。所以一个update函数即可。注意的是,线段树的叶子节点不是x轴或者y轴上的点,而是一个个区间,由矩形的长或者宽间距所构成的区间。比如 你现在要更新的这条边的两个端点在x轴上是 x=1,和x=6,更新的l=1,r=5,因为1->6 中间有5个区间 偷别人博客的一张图来看一下就是这样的效果:

所以线段树维护的是 这些小区间

然后剩下的细节就很好懂了

  1. #include<cstdio>
  2.  
  3. #include<string.h>
  4.  
  5. #include<algorithm>
  6.  
  7. #define inf 0x3f3f3f3f
  8.  
  9. const int maxn=;
  10.  
  11. using namespace std;
  12.  
  13. #define lson (id<<1)
  14.  
  15. #define rson ((id<<1)|1)
  16.  
  17. #define mid ((l+r)>>1)
  18.  
  19. double a[maxn+];
  20.  
  21. double sum[maxn+];
  22.  
  23. int flag[maxn+];
  24.  
  25. int n,l,r,k,cnt,icase;
  26.  
  27. double ans;
  28.  
  29. double X1,Y1,X2,Y2;
  30.  
  31. struct node{
  32. double lx,rx,y;
  33. int f;
  34. node(){};
  35. node(double lx_,double rx_,double y_,int f_){
  36. lx=lx_,rx=rx_,y=y_,f=f_;
  37. }
  38. }line[maxn+];
  39.  
  40. int cmp(node a,node b){
  41. return a.y<b.y;
  42. }
  43.  
  44. int bin_search(double val){
  45. int lb=,ub=k;
  46. int Mid=(lb+ub)>>;
  47. while(ub-lb>){
  48. Mid=(ub+lb)>>;
  49. if(a[Mid]==val) return Mid;
  50. else if(a[Mid]>val) ub=Mid;
  51. else if(a[Mid]<val) lb=Mid;
  52. }
  53. if(a[Mid]==val) return Mid;
  54. if(a[ub]==val) return ub;
  55. if(a[lb]==val) return lb;
  56. }
  57.  
  58. void push_up(int id,int l,int r){
  59. if(flag[id]) sum[id]=a[r+]-a[l];
  60. else if(l==r) sum[id]=;
  61. else sum[id]=sum[lson]+sum[rson];
  62. }
  63.  
  64. void update(int id,int l,int r,int ql,int qr,int val){
  65. if(ql<=l&&r<=qr){
  66. flag[id]+=val;
  67. push_up(id,l,r);
  68. return ;
  69. }
  70. if(ql<=mid){
  71. update(lson,l,mid,ql,qr,val);
  72. }
  73. if(qr>=mid+){
  74. update(rson,mid+,r,ql,qr,val);
  75. }
  76. if(qr<=mid){
  77. update(lson,l,mid,ql,qr,val);
  78. } else if(ql>=mid+){
  79. update(rson,mid+,r,ql,qr,val);
  80. } else {
  81. update(lson,l,mid,ql,mid,val);
  82. update(rson,mid+,r,mid+,qr,val);
  83. }
  84. push_up(id,l,r);
  85. }
  86.  
  87. void init(){
  88. k=;
  89. cnt=;
  90. ans=;
  91. memset(flag,,sizeof(flag));
  92. memset(sum,,sizeof(sum));
  93. }
  94.  
  95. void solve(){
  96. for(int i=;i<=n;i++){
  97. scanf("%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2);
  98. line[++cnt]=node(X1,X2,Y1,);
  99. a[cnt]=X1;
  100. line[++cnt]=node(X1,X2,Y2,-);
  101. a[cnt]=X2;
  102. }
  103. sort(a+,a++cnt);
  104. sort(line+,line++cnt,cmp);
  105. k=;
  106. for(int i=;i<=cnt;i++){
  107. if(a[i]!=a[i+]){
  108. a[++k]=a[i];
  109. }
  110. }
  111. for(int i=;i<cnt;i++){
  112. l=bin_search(line[i].lx);
  113. r=bin_search(line[i].rx)-;
  114. update(,,k,l,r,line[i].f);
  115. ans+=sum[]*(line[i+].y-line[i].y);
  116. }
  117. printf("Test case #%d\n",++icase);
  118. printf("Total explored area: %.2f\n\n",ans);
  119. }
  120.  
  121. int main()
  122. {
  123. while(scanf("%d",&n)!=EOF&&n){
  124. init();
  125. solve();
  126. }
  127. return ;
  128. }

矩形面积并-扫描线 线段树 离散化 模板-poj1151 hdu1542的更多相关文章

  1. hdu1542 矩形面积并(线段树+离散化+扫描线)

    题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...

  2. POJ1151Atlantis 矩形面积并 扫描线 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ1151 题意概括 给出n个矩形,求他们的面积并. n<=100 题解 数据范围极小. 我们分3种 ...

  3. HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)

    题目链接 题意:中文题意. 分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt>=0改成cnt>=2就行了,. 但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了, ...

  4. POJ 1151 Atlantis 矩形面积求交/线段树扫描线

    Atlantis 题目连接 http://poj.org/problem?id=1151 Description here are several ancient Greek texts that c ...

  5. HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板

    好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...

  6. 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)

    [题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...

  7. luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树

    Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...

  8. 【BZOJ4418】[Shoi2013]扇形面积并 扫描线+线段树

    [BZOJ4418][Shoi2013]扇形面积并 Description 给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖. Input 第一行是三个整数n,m,k.n代表同心扇形的个数,m用 ...

  9. BZOJ 1645: [Usaco2007 Open]City Horizon 城市地平线 扫描线 + 线段树 + 离散化

    Code: #include<cstdio> #include<algorithm> #include<string> #define maxn 1030000 # ...

随机推荐

  1. HDU 4336 Card Collector:状压 + 期望dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4336 题意: 有n种卡片(n <= 20). 对于每一包方便面,里面有卡片i的概率为p[i],可 ...

  2. css(4)

    类选择器和id选择器都有父子选择器. 在css文件中国,有时候为了简化样式,可以把相同的样式拿出来放在一起. display:inline display:block 行内元素里只能放行内元素,而块内 ...

  3. laravel基础课程---10、数据库基本操作(如何使用数据库)

    laravel基础课程---10.数据库基本操作(如何使用数据库) 一.总结 一句话总结: 1.链接数据库:.env环境配置里面 2.执行数据库操作:DB::table('users')->up ...

  4. linux 命令:crontab

    一.crond简介 crond 是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务 工具,并且会自动启动c ...

  5. storm源码剖析(2):storm的配置项

    storm的配置项,可以从backtype/storm/Config.java中找到所有配置项及其描述

  6. leetcode 303. Range Sum Query - Immutable(前缀和)

    Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive ...

  7. MySQL多个条件以什么表当做主条件表_20161111周五

    前两天有事情 停了2天 数据需求:1.活动日期11.8-11.10订单2.单笔订单购买A类产品 B类产品满足68元.且连续3天下单的用户ID 首先第一个条件很简单,主要是第二个条件 第二个条件是 且 ...

  8. 【Lintcode】106.Convert Sorted List to Balanced BST

    题目: Given a singly linked list where elements are sorted in ascending order, convert it to a height ...

  9. AtCoder Regular Contest 072 E:Alice in linear land

    题目传送门:https://arc072.contest.atcoder.jp/tasks/arc072_c 题目翻译 给你一个数组\(D\),然后给你一个操作序列\(d\),每次操作可以将\(D\) ...

  10. UDK更改启动画面及载入动画

    转自:http://www.unrealchina.org/forum.php?mod=viewthread&tid=246&extra=page%3D1 方法很简单: 1.更改启动画 ...