pku 3277

#include <iostream> #include <algorithm> using namespace std; #define MAX 40005 struct TNode { int left, right, height; }; TNode T[MAX*10]; int map[MAX][3]; int temp[MAX*2]; __int64 sum; int index; int find(int v) { int low = 0, high = index - 1; int mid; while(low <= high) { mid = (low + high) >> 1; if(v == temp[mid]) return mid; if(v > temp[mid]) low = mid + 1; else high = mid - 1; } return 0; } void build(int s, int t, int step) { T[step].left = s; T[step].right = t; T[step].height = 0; if(t - s <= 1) return; int mid = (s + t) >> 1; build(s, mid, step*2); build(mid, t, step*2+1); } void insert(int s, int t, int height, int step) { if(s == T[step].left && t == T[step].right) { T[step].height = height; return; } if(T[step].height) { T[step*2].height = T[step*2+1].height = T[step].height; T[step].height = 0; } int mid = (T[step].left + T[step].right) >> 1; if(t <= mid) insert(s, t, height, step*2); else if(s >= mid) insert(s, t, height, step*2+1); else { insert(s, mid, height, step*2); insert(mid, t, height, step*2+1); } } void calculate(int step) { if(T[step].height) { sum += (__int64)(temp[T[step].right] - temp[T[step].left])*T[step].height; return; } if(T[step].right - T[step].left <=1) return; calculate(step*2); calculate(step*2+1); } int cmp(const void* lhs, const void* rhs) { return ((int*)lhs)[2] - ((int*)rhs)[2]; } int main() { int N; scanf("%d", &N); for(int i = 0; i < N; ++i) { scanf("%d%d%d", &map[i][0], &map[i][1], &map[i][2]); temp[index++] = map[i][0]; temp[index++] = map[i][1]; } sort(temp, temp+2*N); index = 1; for(int i = 1; i < 2*N; ++i) // 去除temp[]中重复的点 if(temp[i] != temp[i-1]) temp[index++] = temp[i]; build(0, index-1, 1); // 按temp[0...index-1]的下标来建立线段树 qsort(map, N, 3*sizeof(int), cmp); //大的height覆盖小的height for(int i = 0; i < N; ++i) insert(find(map[i][0]), find(map[i][1]), map[i][2], 1); calculate(1); printf("%I64d/n", sum); return 0; } //112 4718856 xiaofengsheng 4064K 282MS C++ 2079B 2009-03-04 10:59:59 //线段树确实很好很强大 //此题是按下标来建立线段树,不同于用坐标的离散化建立的线段树(若这样就会使底 //的长度发生变化以至于面积发生变化),非常经典.而这里可以看作另一种形式的离散化, //把temp[]的下标看作离散的对象 //这种思想很值得细细体会. //注意的问题: // sum 要用__int64; //qsort: qsort(void * _Base,size_t _NumOfElements,size_t _SizeOfElements, (int*)(const void *, const void *)); // 在temp[]中将所有坐标排序,然后去除重复点; // 排序的目的是让后面的大的height覆盖小的height,而不需不断更新height; // find()是为了找出map[i][0],map[i][1]的下标,然后将这条线段插入;

你可能感兴趣的:(c,struct,insert,Build,include)