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 }
  • 相关阅读:
    l2tp ubuntu
    my emacs fav config
    2048小游戏源码(vue自定义指令使用)
    Vue 脚手架新建项目
    vue中修改router定义的name值
    只能输入金额格式的input
    前端开发中UI问题处理
    form表单提交Ajax请求后不跳转
    小程序中代替v-html用法
    小程序中分页加载问题
  • 原文地址:https://www.cnblogs.com/GeniusYang/p/5762577.html
Copyright © 2011-2022 走看看