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\n",tnode[1].sum); //直接输出,头结点的sum值 127 return 0; 128 }