(離散化 + 線段樹) poj 3277 City Horizon

來源:互聯網
上載者:User
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>

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.