离散化真的是一个很神奇的东西,其实就是另建一个hash表映射所有的坐标,在对付总体范围较大或者重复很多的情况时有神奇的效果,前两场比赛时碰到了两道离散化的题目,出现的几率还是很高的,觉得有必要学习一下,但是昨天下午。。。(神啊,原谅我吧!)。
用线段树处理举行并的面积暂时还不会,二维的线段树怎么处理呢?(我猜应该先降低维度)。这道题是求一维的情况,还不算是经典的线段树,只能算离散化的入门题目吧!
线段树很是博大精深啊,有两种经典的建树模型,连续型和分段型,这里采用的是第一种,特别注意的是处理时小心空区,什么是空区呢,就是树中的某一条线段没有值,这里的没有值容易和零值搞混,零值需要继续递归求解,而空区要直接跳出了,所以,预处理和赋值时要区别开着两种情况。
pku 3277代码如下:
代码
1 #include<iostream>
2 #include<algorithm>
3 using namespace std;
4
5 #define MAX 80010
6 struct point{
7 int a,b,h;
8 } p[MAX];
9 struct Node{
10 int l,r,h;
11 } Tree[6*MAX];
12 int hash[MAX],index;
13 __int64 ans;
14 bool cmp(point a,point b)
15 {
16 return a.h < b.h;
17 }
18 void build(int l,int r,int k)
19 {
20 Tree[k].l = l;
21 Tree[k].r = r;
22 Tree[k].h = 0;
23 if (l+1 == r) return;
24 int mid = (l+r)/2;
25 build(l,mid,2*k);
26 build(mid,r,2*k+1);
27 }
28 int find(int x)
29 {
30 int l = 0,r = index-1;
31 while (l <= r){
32 int mid = (l+r)/2;
33 if (hash[mid] == x) return mid;
34 else{
35 if (hash[mid] > x) r = mid-1;
36 else l = mid+1;
37 }
38 }
39 }
40 void update(int l,int r,int h,int k)
41 {
42 if (Tree[k].l == l && Tree[k].r == r) {Tree[k].h = h; return; }
43 if (Tree[k].h >= 0){
44 Tree[2*k].h = Tree[k].h; Tree[2*k+1].h = Tree[k].h; Tree[k].h = -1;
45 }
46 int mid=(Tree[k].l+Tree[k].r)/2;
47 if (l >= mid) update(l,r,h,2*k+1);
48 else if (r <= mid) update(l,r,h,2*k);
49 else {update(l,mid,h,2*k); update(mid,r,h,2*k+1); }
50
51 }
52 void solve(int k)
53 {
54 if (Tree[k].h > 0) {ans += (hash[Tree[k].r]-hash[Tree[k].l])*__int64(Tree[k].h); return;}
55 else if (Tree[k].h == -1){
56 solve(2*k);
57 solve(2*k+1);
58 }
59 }
60 int main()
61 {
62 int n,nn,i;
63 while (scanf ("%d",&n) != EOF){
64 for (i = 0,index = 0; i< n; i++){
65 scanf ("%d%d%d",&p[i].a,&p[i].b,&p[i].h);
66 hash[index++] = p[i].a; hash[index++] = p[i].b;
67 }
68 sort(hash,hash+index); sort(p,p+n,cmp);
69 for (i = 1,nn = index,index = 1; i< nn; i++)
70 if (hash[i] != hash[i-1]) hash[index++] = hash[i];
71 build(0,index-1,1);
72 for (i = 0; i < n; i++)
73 update(find(p[i].a),find(p[i].b),p[i].h,1);
74 ans = 0; solve(1);
75 printf ("%I64d\n",ans);
76 }
77 return 0;
78 }