City Horizon
| Time Limit: 2000MS |
|
Memory Limit: 65536K |
| Total Submissions: 10318 |
|
Accepted: 2704 |
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
42 5 19 10 46 8 24 6 3
Sample Output
16
Hint
The first building overlaps with the fourth building for an area of 1 square unit, so the total area is just 3*1 + 1*4 + 2*2 + 2*3 - 1 = 16.線段樹的概念:參考<<線段樹在資訊學競賽中的應用>>武漢大學和<<線段樹>>/*<br />題目大意:在一條水平線上有N個建築物,建築物都是長方形的,且可以互相遮蓋。給出每個建築物的左右座標值Ai,Bi以及每個建築物的高度Hi,<br />:需要計算出這些建築物總共覆蓋的面積。<br />題目解答:由於Ai,Bi∈[1,1000000000],直接將線段[Ai,Bi]插入線段樹空間消耗太大,<br />:可以將這n條線段的2n個端點離散化到一個數組X[0...2n-1],</p><p>Source Code</p><p>Problem: 3277 User: wawadimu<br />Memory: 4188K Time: 282MS<br />Language: C++ Result: Accepted </p><p>Source Code<br />*/<br />#include<iostream><br />#include<algorithm><br />using namespace std;</p><p>#define maxn 40010</p><p>struct Node //區間[l,r]內 h = 房子的最高值<br />{<br />int l,r,h;<br />}tree[7*maxn];//開小了就運行出錯,不知為什麼3倍不行</p><p>struct XX //未經處理資料(左右座標,高度)<br />{<br />int ai,bi,h;<br />}res[maxn];</p><p>int t[2*maxn];//原始座標<br />int hash[maxn];//離散化座標--空間壓縮<br />void built(int num,int L ,int R);//建立線段樹<br />void insert(int num,int L ,int R,int H);//維護線段樹<br />int query(int L, int R ,int t);//尋找離散化的區間<br />long long Count(int num);//統計面積</p><p>int cmp ( XX a, XX b)//按告訴從小到大排列<br />{<br />return a.h < b.h;<br />}</p><p>int main()<br />{<br />//freopen("3277.txt","r",stdin);<br />int n , len , i , j , k ;<br />int ai , bi , h ;<br />int cnt;<br />while(scanf("%d",&n)!=EOF)<br />{<br />k=0;<br />for(i=0; i<n; i++)<br />{<br />scanf("%d%d%d",&ai,&bi,&h);<br />t[k++]=ai; t[k++]=bi;<br />res[i].ai=ai; res[i].bi=bi; res[i].h=h;<br />}<br />sort( t , t+k );//排序<br />sort( res, res+ n , cmp);//高度排序<br />cnt=0;<br />hash[cnt++]=t[0];<br />for(i=1 ; i<k ;i++)//離散化<br />{<br />if(t[i] != t[i-1]) hash[cnt++]=t[i];<br />}<br />cnt--;<br />//for(i=1;i<=cnt;i++) cout<<hash[i]<<" ";cout<<endl;<br />built(1,0,cnt);<br />for(i=0; i <n ; i++)<br />{<br />int l=query(0, cnt , res[i].ai),<br />r=query(l, cnt , res[i].bi);<br />insert(1,l,r,res[i].h);//更新區間[l,r]的資料 h<br />}<br />long long ans=Count(1);<br />printf("%lld/n",ans);</p><p>}<br />return 0;<br />}<br />void built(int num,int L, int R)<br />{</p><p>tree[num].l=L ; tree[num].r=R;//cout<<L<<":"<<R<<" ";<br />tree[num].h=-1;//區間未覆蓋<br />if(L+1 == R) { return ;}<br />else<br />{<br />int M=(L+R)>>1;<br />built(2*num,L,M);<br />built(2*num+1,M,R);<br />}<br />}<br />void insert(int num, int L, int R ,int H)<br />{<br />//cout<<L<<":"<<R<<"="<<H<<"->"<<tree[num].l<<tree[num].r<<" "<<tree[num].h<<" ";<br />if(H <= tree[num].h) return;<br />if(L==tree[num].l && R==tree[num].r ) { tree[num].h=H; return;}<br />if(tree[num].h >=0 && tree[num].l +1 != tree[num].r)<br />{ tree[2*num].h=tree[2*num+1].h=tree[num].h; tree[num].h=-1; }<br />int M=(tree[num].l+tree[num].r)>>1;<br />if( R <= M) { insert( 2*num , L , R , H ); }<br />else if( L >=M ) { insert( 2*num+1 , L , R , H ); }<br />else { insert( 2*num , L , M , H );<br />insert( 2*num+1 , M , R , H ); }<br />}<br />int query(int L, int R ,int d)<br />{<br />int mid,l=L,r=R;<br />while( l<= r)<br />{<br />mid=(l+r)>>1;<br />if( d==hash[mid] ) return mid;<br />else if(hash[mid] > d) r=mid-1;<br />else l=mid+1;<br />}<br />return -1;<br />}<br />long long Count(int num)<br />{<br />if(tree[num].l +1 == tree[num].r && tree[num].h < 0) return 0;<br />if(tree[num].h >0) return tree[num].h*(long long )(hash[tree[num].r]-hash[tree[num].l]);<br />else return Count(2*num) + Count(2*num+1);<br />}/*<br />網上代碼<br />Source Code</p><p>Problem: 3277 User: wawadimu<br />Memory: 5436K Time: 219MS<br />Language: C++ Result: Accepted </p><p>Source Code<br />*/<br />#include <cstdio><br />#include <iostream><br />#include <algorithm><br />using namespace std;<br />int A[40001],B[40001],H[40001],N=0,i,j=0,n=0,low,high,mid,LS[80002]={0},S[80001]={0};<br />struct{<br /> int l,r,h,m;<br />}tree[300000]={0};<br />void build(int p,int l,int r){<br /> tree[p].l=l;tree[p].r=r;<br /> if(r-l>1){<br /> int m=(l+r)>>1;<br /> tree[p].m=m;<br /> build(2*p,l,m);<br /> build(2*p+1,m,r);<br /> }<br />}<br />void insert(int p,int a,int b){<br /> if(S[tree[p].l]==a&&S[tree[p].r]==b){<br /> if(tree[p].h<H[i])tree[p].h=H[i];<br /> return;<br /> }<br /> int tmp=S[tree[p].m];<br /> if(b<=tmp)insert(2*p,a,b);<br /> else if(a>=tmp)insert(2*p+1,a,b);<br /> else{<br /> insert(2*p,a,tmp);<br /> insert(2*p+1,tmp,b);<br /> }<br />}<br />long long Count(int p,int h){<br /> if(h>tree[p].h)tree[p].h=h;<br /> if(tree[p].r-tree[p].l==1)return (long long)(S[tree[p].r]-S[tree[p].l])*tree[p].h;<br /> return Count(2*p,tree[p].h)+Count(2*p+1,tree[p].h);<br />}<br />int main(){<br /> //freopen("3277.txt","r",stdin);<br /> scanf("%d",&n);<br /> for(i=1;i<=n;i++){<br /> scanf("%d%d%d",&A[i],&B[i],&H[i]);<br /> LS[++j]=A[i];<br /> LS[++j]=B[i];<br /> }<br /> sort(LS+1,LS+1+j);<br /> for(i=1;i<=j;i++){<br /> S[++N]=LS[i];<br /> while(LS[i+1]==LS[i])i++;<br /> }<br /> build(1,1,N);<br /> for(i=1;i<=n;i++)<br /> insert(1,A[i],B[i]);<br /> cout<<Count(1,0)<<endl;<br /> return 0;<br />}</p><p>