zoukankan      html  css  js  c++  java
  • 矩形面积并-扫描线 线段树 离散化 模板-poj1151 hdu1542

    今天刚看到这个模板我是懵逼的,这个线段树既没有建树,也没有查询,只有一个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=1000;
     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+10];
     20 
     21 double sum[maxn+10];
     22 
     23 int flag[maxn+10];
     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+10];
     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=1,ub=k;
     46     int Mid=(lb+ub)>>1;
     47     while(ub-lb>1){
     48         Mid=(ub+lb)>>1;
     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+1]-a[l];
     60    else if(l==r) sum[id]=0;
     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+1){
     74         update(rson,mid+1,r,ql,qr,val);
     75       }
     76       if(qr<=mid){
     77         update(lson,l,mid,ql,qr,val);
     78       } else if(ql>=mid+1){
     79         update(rson,mid+1,r,ql,qr,val);
     80       } else {
     81         update(lson,l,mid,ql,mid,val);
     82         update(rson,mid+1,r,mid+1,qr,val);
     83       }
     84       push_up(id,l,r);
     85 }
     86 
     87 void init(){
     88   k=0;
     89   cnt=0;
     90   ans=0;
     91   memset(flag,0,sizeof(flag));
     92   memset(sum,0,sizeof(sum));
     93 }
     94 
     95 void solve(){
     96         for(int i=1;i<=n;i++){
     97                 scanf("%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2);
     98                 line[++cnt]=node(X1,X2,Y1,1);
     99                 a[cnt]=X1;
    100                 line[++cnt]=node(X1,X2,Y2,-1);
    101                 a[cnt]=X2;
    102         }
    103         sort(a+1,a+1+cnt);
    104         sort(line+1,line+1+cnt,cmp);
    105         k=1;
    106         for(int i=2;i<=cnt;i++){
    107                if(a[i]!=a[i+1]){
    108                 a[++k]=a[i];
    109                }
    110         }
    111         for(int i=1;i<cnt;i++){
    112              l=bin_search(line[i].lx);
    113              r=bin_search(line[i].rx)-1;
    114              update(1,1,k,l,r,line[i].f);
    115              ans+=sum[1]*(line[i+1].y-line[i].y);
    116         }
    117         printf("Test case #%d
    ",++icase);
    118         printf("Total explored area: %.2f
    
    ",ans);
    119 }
    120 
    121 int main()
    122 {
    123     while(scanf("%d",&n)!=EOF&&n){
    124         init();
    125         solve();
    126     }
    127     return 0;
    128 }
  • 相关阅读:
    Asp.net 动态添加Meta标签
    【转】在SharePoint Server 2010中更改“我的网站”
    SPQuery DateTime 类型查询
    Asp.net Web Application 打开 SharePoint 2010 Site 错误 The Web application at could not be found
    How To Create SharePoint 2010 Site Collection In Its Own DB
    C# 文件打印
    面试题 java集合
    《深入理解Java虚拟机》(六)堆内存使用分析,垃圾收集器 GC 日志解读
    《深入理解Java虚拟机》(五)JVM调优
    《深入理解Java虚拟机》(四)虚拟机性能监控与故障处理工具
  • 原文地址:https://www.cnblogs.com/GeniusYang/p/5762577.html
Copyright © 2011-2022 走看看