zoukankan      html  css  js  c++  java
  • codevs 3044 矩形面积求并 || hdu 1542

    这个线段树的作用其实是维护一组(1维 平面(?) 上的)线段覆盖的区域的总长度,支持加入/删除一条线段。

    线段树只能维护整数下标,因此要离散化。

    也可以理解为将每一条处理的线段分解为一些小线段,要求每一条要处理的线段都能这么分解

    注意端点,线段树维护的是线段,而查询是端点,可能需要稍微变一下

    具体的query方法好像类似标记永久化(?)

    感觉不优美啊。。。想了一会并没有想到更好的方法。。。。

    codevs:

    错误记录:

    1.打成unordered_map<int,int>

    2.70、75行两个tlen误为len

    3.要求保留两位小数

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<tr1/unordered_map>
     4 using namespace std;
     5 using namespace tr1;
     6 struct Q
     7 {
     8     int x1,x2;double y1,y2,tx1,tx2;
     9 }q[101];
    10 struct QQ
    11 {
    12     int l,r;double h;int fl;
    13     friend bool operator<(const QQ &a,const QQ &b)    {return a.h<b.h;}
    14 }qq[202];
    15 double tt[202];
    16 unordered_map<double,int> ma;
    17 int len,tlen;double ans;
    18 int n;
    19 namespace SegT
    20 {
    21 #define lc (num<<1)
    22 #define rc (num<<1|1)
    23 #define mid (l+((r-l)>>1))
    24 //[l,r]表示点l到点r+1之间的线段
    25     int cover[2010];double dat[2010];
    26     int L,R,x;
    27     void build(int l,int r,int num)
    28     {
    29         cover[num]=0;dat[num]=0;
    30         if(l!=r)    build(l,mid,lc),build(mid+1,r,rc);
    31     }
    32     void addx(int l,int r,int num)
    33     {
    34         if(L<=l&&r<=R)
    35         {
    36             cover[num]+=x;
    37             if(cover[num])    dat[num]=tt[r+1]-tt[l];
    38             else    dat[num]=dat[lc]+dat[rc];
    39             return;
    40         }
    41         if(L<=mid)    addx(l,mid,lc);
    42         if(mid<R)    addx(mid+1,r,rc);
    43         if(cover[num])    dat[num]=tt[r+1]-tt[l];
    44         else    dat[num]=dat[lc]+dat[rc];
    45     }
    46 #undef lc
    47 #undef rc
    48 #undef mid
    49 }
    50 int main()
    51 {
    52     int i;
    53     while(1)
    54     {
    55         scanf("%d",&n);len=tlen=0;ans=0;ma.clear();
    56         if(n==0)    break;
    57         for(i=1;i<=n;i++)
    58         {
    59             scanf("%lf%lf%lf%lf",&q[i].tx1,&q[i].y1,&q[i].tx2,&q[i].y2);
    60             tt[++tlen]=q[i].tx1;tt[++tlen]=q[i].tx2;
    61         }
    62         sort(tt+1,tt+tlen+1);tlen=unique(tt+1,tt+tlen+1)-tt-1;
    63         for(i=1;i<=tlen;i++)    ma[tt[i]]=i;
    64         for(i=1;i<=n;i++)    q[i].x1=ma[q[i].tx1],q[i].x2=ma[q[i].tx2]-1;
    65         for(i=1;i<=n;i++)
    66         {
    67             qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y1,1};
    68             qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y2,-1};
    69         }
    70         sort(qq+1,qq+len+1);SegT::build(1,tlen-1,1);
    71         for(i=1;i<=len;i++)
    72         {
    73             ans+=SegT::dat[1]*(qq[i].h-qq[i-1].h);
    74             SegT::L=qq[i].l;SegT::R=qq[i].r;SegT::x=qq[i].fl;
    75             SegT::addx(1,tlen-1,1);
    76         }
    77         printf("%.2lf
    ",ans);
    78     }
    79     return 0;
    80 }

    hdu

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<tr1/unordered_map>
     4 using namespace std;
     5 using namespace tr1;
     6 struct Q
     7 {
     8     int x1,x2;double y1,y2,tx1,tx2;
     9 }q[101];
    10 struct QQ
    11 {
    12     int l,r;double h;int fl;
    13     friend bool operator<(const QQ &a,const QQ &b)    {return a.h<b.h;}
    14 }qq[202];
    15 double tt[202];
    16 unordered_map<double,int> ma;
    17 int len,tlen;double ans;
    18 int n;
    19 namespace SegT
    20 {
    21 #define lc (num<<1)
    22 #define rc (num<<1|1)
    23 #define mid (l+((r-l)>>1))
    24 //[l,r]表示点l到点r+1之间的线段
    25     int cover[2010];double dat[2010];
    26     int L,R,x;
    27     void build(int l,int r,int num)
    28     {
    29         cover[num]=0;dat[num]=0;
    30         if(l!=r)    build(l,mid,lc),build(mid+1,r,rc);
    31     }
    32     void addx(int l,int r,int num)
    33     {
    34         if(L<=l&&r<=R)
    35         {
    36             cover[num]+=x;
    37             if(cover[num])    dat[num]=tt[r+1]-tt[l];
    38             else    dat[num]=dat[lc]+dat[rc];
    39             return;
    40         }
    41         if(L<=mid)    addx(l,mid,lc);
    42         if(mid<R)    addx(mid+1,r,rc);
    43         if(cover[num])    dat[num]=tt[r+1]-tt[l];
    44         else    dat[num]=dat[lc]+dat[rc];
    45     }
    46 #undef lc
    47 #undef rc
    48 #undef mid
    49 }
    50 int main()
    51 {
    52     int i,T=0;
    53     while(1)
    54     {
    55         scanf("%d",&n);len=tlen=0;ans=0;ma.clear();
    56         if(n==0)    break;
    57         for(i=1;i<=n;i++)
    58         {
    59             scanf("%lf%lf%lf%lf",&q[i].tx1,&q[i].y1,&q[i].tx2,&q[i].y2);
    60             tt[++tlen]=q[i].tx1;tt[++tlen]=q[i].tx2;
    61         }
    62         sort(tt+1,tt+tlen+1);tlen=unique(tt+1,tt+tlen+1)-tt-1;
    63         for(i=1;i<=tlen;i++)    ma[tt[i]]=i;
    64         for(i=1;i<=n;i++)    q[i].x1=ma[q[i].tx1],q[i].x2=ma[q[i].tx2]-1;
    65         for(i=1;i<=n;i++)
    66         {
    67             qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y1,1};
    68             qq[++len]=(QQ){q[i].x1,q[i].x2,q[i].y2,-1};
    69         }
    70         sort(qq+1,qq+len+1);SegT::build(1,tlen-1,1);
    71         for(i=1;i<=len;i++)
    72         {
    73             ans+=SegT::dat[1]*(qq[i].h-qq[i-1].h);
    74             SegT::L=qq[i].l;SegT::R=qq[i].r;SegT::x=qq[i].fl;
    75             SegT::addx(1,tlen-1,1);
    76         }
    77         printf("Test case #%d
    Total explored area: %.2lf
    
    ",++T,ans);
    78     }
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    差分序列
    蓝桥杯 操作格子
    线段树
    历届题目 密文搜索
    对局匹配(动态规划)
    历届试题 分巧克力(二分查找)
    第九届蓝桥杯B组决赛 调手表(完全背包)
    快速幂求余
    2019蓝桥杯国赛备赛题库
    ubuntu16.04安装cuda8.0试错锦集
  • 原文地址:https://www.cnblogs.com/hehe54321/p/8763421.html
Copyright © 2011-2022 走看看