codevs3044 线段树+扫描线

Posted blues

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codevs3044 线段树+扫描线相关的知识,希望对你有一定的参考价值。

3044 矩形面积求并

http://hzwer.com/879.html

扫描线

  1 // #pragma comment(linker, "/STACK:1024000000,1024000000")
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <sstream>
  6 #include <string>
  7 #include <algorithm>
  8 #include <list>
  9 #include <map>
 10 #include <vector>
 11 #include <queue>
 12 #include <stack>
 13 #include <cmath>
 14 #include <cstdlib>
 15 // #include <conio.h>
 16 using namespace std;
 17 #define clc(a,b) memset(a,b,sizeof(a))
 18 #define inf 0x3f3f3f3f
 19 #define lson l,mid,rt<<1
 20 #define rson mid+1,r,rt<<1|1
 21 const int N = 1100;
 22 const int MOD = 1e9+7;
 23 #define LL long long
 24 #define mi() (l+r)>>1
 25 double const pi = acos(-1);
 26 
 27 // inline int r() {
 28 //     int x=0,f=1;char ch=getchar();
 29 //     while(ch>\'9\'||ch<\'0\') {if(ch==\'-\') f=-1;ch=getchar();}
 30 //     while(ch>=\'0\'&&ch<=\'9\') { x=x*10+ch-\'0\';ch=getchar();}return x*f;
 31 // }
 32 int n;
 33 double hashh[N<<2];
 34 double sum[N<<2];
 35 int color[N<<2];
 36 struct Edge{
 37      double x1,x2,y;
 38      int flag;
 39      bool operator < (const Edge &a) const{
 40          return y<a.y;
 41      }
 42 }e[N<<2];
 43 
 44 int b_s(double x){
 45      int l=1,r=2*n;
 46      int mid;
 47      while(l<=r){
 48           mid=(l+r)>>1;
 49           if(hashh[mid]==x) return mid;
 50           else if(hashh[mid]<x) l=mid+1;
 51           else r=mid-1;
 52      }
 53 }
 54 
 55 void pushdown(int rt,int l,int r){
 56      if(color[rt]) sum[rt]=hashh[r+1]-hashh[l];
 57      else if(l==r) sum[rt]=0;
 58      else sum[rt]=sum[rt<<1]+sum[rt<<1|1];
 59 }
 60 
 61 void update(int l,int r,int rt,int x,int y,int f){
 62      if(x==l&&y==r){
 63           color[rt]+=f;
 64           pushdown(rt,l,r);
 65           return;
 66      }
 67      int mid=mi();
 68      if(y<=mid) update(l,mid,rt<<1,x,y,f);
 69      else if(x>mid) update(mid+1,r,rt<<1|1,x,y,f);
 70      else {
 71          update(l,mid,rt<<1,x,mid,f);
 72          update(mid+1,r,rt<<1|1,mid+1,y,f);
 73      }
 74      pushdown(rt,l,r);
 75 }
 76 int main(){
 77      // int n;
 78      while(scanf("%d",&n)){
 79          if(n==0)
 80             break;
 81          clc(color,0);
 82          clc(sum,0); 
 83          double x1,x2,y1,y2;
 84          for(int i=1;i<=n;i++){
 85              scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
 86              e[i*2-1].x1=e[i*2].x1=x1;
 87              e[i*2-1].x2=e[i*2].x2=x2;
 88              e[i*2-1].y=y1;e[i*2].y=y2;
 89              e[i*2-1].flag=1;e[i*2].flag=-1;
 90              hashh[i*2-1]=x1;hashh[i*2]=x2;
 91          }
 92          sort(e+1,e+1+2*n);
 93          sort(hashh+1,hashh+1+2*n);
 94          double ans=0;
 95          for(int i=1;i<=2*n;i++){
 96              int l=b_s(e[i].x1),r=b_s(e[i].x2)-1;
 97              // cout<<"l:"<<l<<" "<<"r:"<<r<<endl;
 98              if(l<=r) update(1,2*n,1,l,r,e[i].flag);
 99              // cout<<"sum[1]"<<sum[1]<<endl;
100              ans+=sum[1]*(e[i+1].y-e[i].y);
101          }
102          printf("%.2f\\n",ans);
103      }
104      return 0;
105 }

 

以上是关于codevs3044 线段树+扫描线的主要内容,如果未能解决你的问题,请参考以下文章

[Codevs] 矩形面积求并

codevs3044(扫描线学习)

线段树模板合集(CodeVS1080 1081 1082 4597)Pascal代码

codevs1228 (dfs序+线段树)

codevs 3044 矩形面积求并

codevs 4919 线段树练习4