zoukankan      html  css  js  c++  java
  • 洛谷 1382 楼房

    【题解】

      本题要计算矩形组成的轮廓线,可以用线段树来实现。

      由于区间长度很大,不能直接开线段数记录,我们要先进行离散化。(显然拐点只可能出现在矩形的左右两边上)然后逐个加入矩形并维护每个位置的最大值。最后对每个拐点可能的位置进行查询并统计答案即可。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define ls (u<<1)
     4 #define rs (u<<1|1)
     5 #define mid ((a[u].l+a[u].r)>>1)
     6 using namespace std;
     7 const int maxn=800010;
     8 int n,N,m,h[maxn],l[maxn],r[maxn],l0[maxn],r0[maxn],s[maxn];
     9 struct tree{int l,r,max,del;}a[maxn];
    10 struct point{int x,y;}ans[maxn];
    11 inline int read(){
    12     int k=0,f=1; char c=getchar();
    13     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    14     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    15     return k*f;
    16 }
    17 void build(int u,int l,int r){
    18     a[u].l=l; a[u].r=r; a[u].max=0;
    19     if(l<r) build(ls,l,mid),build(rs,mid+1,r);
    20 }
    21 void pushdown(int u){
    22     a[ls].max=max(a[ls].max,a[u].del); a[rs].max=max(a[rs].max,a[u].del); 
    23     a[ls].del=max(a[ls].del,a[u].del); a[rs].del=max(a[rs].del,a[u].del); a[u].del=0;
    24 }
    25 void update(int u,int l,int r,int del){
    26     if(l<=a[u].l&&a[u].r<=r){a[u].max=max(a[u].max,del); a[u].del=max(a[u].del,del); return;}
    27     pushdown(u);
    28     if(l<=mid) update(ls,l,r,del);
    29     if(r>mid) update(rs,l,r,del);
    30     a[u].max=max(a[ls].max,a[rs].max);
    31 }
    32 int query(int u,int pos){
    33     if(a[u].l==a[u].r) return a[u].max;
    34     pushdown(u);
    35     if(pos<=mid) return query(ls,pos); else return query(rs,pos);
    36 }
    37 inline void Prepare(){
    38     m=read();
    39     for(int i=1;i<=m;i++) h[i]=read(),s[++n]=l0[i]=read(),s[++n]=r0[i]=read();
    40     sort(s+1,s+1+n); N=unique(s+1,s+1+n)-s-1;
    41     for(int i=1;i<=m;i++)
    42         l[i]=lower_bound(s+1,s+1+N,l0[i])-s,
    43         r[i]=lower_bound(s+1,s+1+N,r0[i])-s;
    44 }
    45 int main(){
    46     Prepare(); build(1,1,N+1);
    47     for(int i=1;i<=m;i++) update(1,l[i],r[i]-1,h[i]);
    48 //    for(int i=1;i<=N+1;i++) printf("%d
    ",query(1,i));
    49     int last=0,tot=0;
    50     for(int i=1;i<=N+1;i++){
    51         int now=query(1,i);
    52         if(now!=last){
    53             ans[++tot]=(point){s[i],last};
    54             ans[++tot]=(point){s[i],now};
    55         }
    56         last=now;
    57     }
    58     printf("%d
    ",tot);
    59     for(int i=1;i<=tot;i++) printf("%d %d
    ",ans[i].x,ans[i].y);
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    char/byte/short类型的加法和类型转换问题
    Java四种基本数据类型
    Git知识集锦
    解决给自己的博客添加百度统计不能验证的问题
    C++静态代码分析工具推荐——PVS-Studio
    Qt在控件未显示时如何获取正确的控件尺寸
    C#程序如何捕捉未try/catch的异常——不弹“XXX已停止工作”报错框
    win10下vs2015编译的程序如何运行在win7等系统(无需安装Redistributable)
    Qt分页导航控件
    win server 2008配置ftp无法登陆问题的解决办法
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8195552.html
Copyright © 2011-2022 走看看