pku 3277 City Horizon(离散化+线段树)

 

因为坐标范围太大,所以将输入的坐标离散化,排序后用下标来代替,线段树插入操作的时候用binary_search来查找坐标对应的下标。因为height大的影子总是会覆盖height小的影子,所以将输入按height排序后再插入线段树,会省掉很多麻烦。

 

#include <iostream> #include <algorithm> using namespace std; #define MaxBuilding 40005 struct node { int height,left,right; }My_Tree[MaxBuilding*8];//我感觉开到max的2倍就足够了,但却一直 run time error,开大点就好了 int temp[MaxBuilding*2];//用于将坐标离散化,用下标来建线段树 int input_data[MaxBuilding][3]; __int64 ans=0; int n; int My_Bsearch(int value)//二分查找,将数据离散化后再查找的时候要用的 { int left=0,right=2*n-1,mid; while(left<=right) { mid=(left+right)/2; if(temp[mid]==value) return mid; else if(value>temp[mid]) left=mid+1; else right=mid-1; } } int cmp(const void* a,const void *b) { return ((int*)a)[2]-((int*)b)[2]; } void build(int a,int b,int i)//递归建树 { My_Tree[i].left=a; My_Tree[i].right=b; My_Tree[i].height=0; if(b-a>1) { build(a,(a+b)/2,i*2); build((a+b)/2,b,i*2+1); } } void insert(int a,int b,int c,int i) { if(My_Tree[i].left==a&&My_Tree[i].right==b) My_Tree[i].height=c; else { if(My_Tree[i].height!=0) //当出现height更大,区间更小的覆盖时,需要特殊处理。方便后面的面积计算。 { My_Tree[i*2].height=My_Tree[i*2+1].height=My_Tree[i].height; My_Tree[i].height=0; } int mid=(My_Tree[i].left+My_Tree[i].right)/2; if(b<=mid) insert(a,b,c,i*2); else if(a>=mid) insert(a,b,c,i*2+1); else { insert(a,mid,c,i*2); insert(mid,b,c,i*2+1); } } } void cal(int i) { if(My_Tree[i].height>0) ans+=(__int64)(temp[My_Tree[i].right]-temp[My_Tree[i].left])*My_Tree[i].height; else if(My_Tree[i].right-My_Tree[i].left>1) { cal(i*2); cal(i*2+1); } } int main() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d%d",&input_data[i][0],&input_data[i][1],&input_data[i][2]); temp[i*2]=input_data[i][0]; temp[i*2+1]=input_data[i][1]; } sort(temp,temp+n*2);//排序,将坐标离散化 build(0,n*2-1,1);//以下标作为线段树的划分,大大减小了树的规模 qsort(input_data,n,sizeof(int)*3,cmp);//将输入按height排序,可以为后面省去不少麻烦 for(int i=0;i<n;i++) { insert(My_Bsearch(input_data[i][0]),My_Bsearch(input_data[i][1]),input_data[i][2],1); } cal(1); printf("%I64d/n",ans); return 0; } 

 

你可能感兴趣的:(pku 3277 City Horizon(离散化+线段树))