zoukankan      html  css  js  c++  java
  • poj City Horizon (线段树+二分离散)

    http://poj.org/problem?id=3277

    City Horizon
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 15255   Accepted: 4111

    Description

    Farmer John has taken his cows on a trip to the city! As the sun sets, the cows gaze at the city horizon and observe the beautiful silhouettes formed by the rectangular buildings.

    The entire horizon is represented by a number line with N (1 ≤ N ≤ 40,000) buildings. Building i's silhouette has a base that spans locations Ai through Bi along the horizon (1 ≤ Ai < Bi ≤ 1,000,000,000) and has height Hi(1 ≤ Hi ≤ 1,000,000,000). Determine the area, in square units, of the aggregate silhouette formed by all N buildings.

    Input

    Line 1: A single integer: N  Lines 2..N+1: Input line i+1 describes building i with three space-separated integers: Ai, Bi, and Hi

    Output

    Line 1: The total area, in square units, of the silhouettes formed by all N buildings

    Sample Input

    4
    2 5 1
    9 10 4
    6 8 2
    4 6 3

    Sample Output

    16

    【题解】:
        这题是二分离散线段树,因为1 ≤Ai<Bi≤ 1,000,000,000,1 ≤Hi≤ 1,000,000,000显然直接建树是不可能的,因为N<40000,数据量不大可以先离散化再建树
        先将输入的Ai Bi Hi 保存在结构体node中,将Ai,Bi保存到一个index数组里面,排序,去重,这样每个Ai,Bi对应一个index数组的位置;
        结构体node按照高度Hi排序,排序之后就不用考虑覆不覆盖的问题了,统一覆盖就行了;
        
        【注】:被坑了,还是自己不够严谨的问题,居然数据类型以为只要用来求和的sum是__int64就可以了,可是在进行乘法的时候height*(r-l)溢出了,果断height__int64过了
        坑惨了,有图有真相:
        


    【code】:

      1 /**
      2 status:Accepted        memory:7424K    
      3 time:407MS        language:C++    
      4 code length:2904B   author:cj    
      5 oj: poj   submittime:2013-08-06 12:36:08
      6 */
      7 
      8 #include<iostream>
      9 #include<stdio.h>
     10 #include<algorithm>
     11 #include<string.h>
     12 
     13 using namespace std;
     14 
     15 #define N 40010
     16 #define lson p<<1
     17 #define rson p<<1|1
     18 
     19 
     20 struct Nod
     21 {
     22     int from,to,height;
     23 }node[N];
     24 
     25 struct TNod
     26 {
     27     int l,r;
     28     __int64 height;  //我以为只要sum值设为__int64就行了,height值也应该是__int64的,因为后面要进行乘法运算
     29     __int64 sum;
     30 }tnode[N<<4];
     31 
     32 bool cmp(Nod a,Nod b) //按高度排序
     33 {
     34     return a.height<b.height;
     35 }
     36 
     37 int temp[N<<2],index[N<<2],brush[N<<2];
     38 
     39 int findPos(int a,int k)  //二分查找离散
     40 {
     41     int l,r,mid=-1;
     42     l=1;
     43     r=k;
     44     while(l<=r)
     45     {
     46         mid = (l+r)>>1;
     47         if(a<index[mid])  r=mid-1;
     48         else if(a>index[mid])   l=mid+1;
     49         else return mid;
     50     }
     51     return mid;
     52 }
     53 
     54 void building(int l,int r,int p)  //建树
     55 {
     56     tnode[p].l = l;
     57     tnode[p].r = r;
     58     tnode[p].height = 0;
     59     tnode[p].sum = 0;
     60     if(l+1==r)    return;
     61     int mid = (l+r)>>1;
     62     building(l,mid,lson);
     63     building(mid,r,rson);
     64 }
     65 
     66 void update(int l,int r,int p,int h)
     67 {
     68     if(tnode[p].l==l&&r==tnode[p].r)
     69     {
     70         tnode[p].height = h;
     71         tnode[p].sum = (index[r]-index[l])*tnode[p].height;  //这里的height是64位int,相乘得64为int
     72         return;
     73     }
     74     if(tnode[p].height>0)  //向下更新
     75     {
     76         tnode[lson].sum = (index[tnode[lson].r] - index[tnode[lson].l])*tnode[p].height;
     77         tnode[rson].sum = (index[tnode[rson].r] - index[tnode[rson].l])*tnode[p].height;
     78         tnode[lson].height = tnode[rson].height = tnode[p].height;
     79         tnode[p].height = 0;
     80     }
     81     int mid = (tnode[p].l+tnode[p].r)>>1;
     82     if(r<=mid)  update(l,r,lson,h);
     83     else if(l>=mid)  update(l,r,rson,h);
     84     else
     85     {
     86         update(l,mid,lson,h);
     87         update(mid,r,rson,h);
     88     }
     89     if(tnode[lson].height&&tnode[rson].height&&tnode[lson].height==tnode[rson].height)  //向上更新
     90     {
     91         tnode[p].height = tnode[lson].height;
     92     }
     93     tnode[p].sum = tnode[lson].sum + tnode[rson].sum;   //向上更新
     94 }
     95 
     96 int main()
     97 {
     98     int n;
     99     scanf("%d",&n);
    100     int i,cnt=0;
    101     for(i=0;i<n;i++)
    102     {
    103         scanf("%d%d%d",&node[i].from,&node[i].to,&node[i].height);
    104         temp[cnt++]=node[i].from;
    105         temp[cnt++]=node[i].to;
    106     }
    107     sort(temp,temp+cnt);  //排序
    108     int j=1;
    109     index[1]=temp[0];
    110     for(i=1;i<cnt;i++)  //去掉重复值
    111     {
    112         if(index[j]!=temp[i])
    113         {
    114             index[++j]=temp[i];
    115         }
    116     }
    117     int k = j;
    118     building(1,k,1);
    119     sort(node,node+n,cmp);  //按照高度排序
    120     for(i=0;i<n;i++)
    121     {
    122         int from = findPos(node[i].from,k);
    123         int to = findPos(node[i].to,k);
    124         update(from,to,1,node[i].height);
    125     }
    126     printf("%I64d
    ",tnode[1].sum);  //直接输出,头结点的sum值
    127     return 0;
    128 }
  • 相关阅读:
    网络编程 TCP
    网络编程之 osi七层协议
    面向对象之元类,单例
    面向对象之异常处理
    面向对象之多态
    面向对象之封装
    mysql 单表查询
    mysql 行(记录)的详细操作
    mysql 库表的操作
    数据库初识
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3240357.html
Copyright © 2011-2022 走看看