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 }
原文地址:https://www.cnblogs.com/crazyapple/p/3240357.html