静态排序二叉树

原文链接:http://www.cnblogs.com/xiao_wu/archive/2010/05/19/1739192.html

    POJ2482 Stars in Your Window

    http://acm.pku.edu.cn/JudgeOnline/problem?id=2482

    此题在黑书上面有解答,但是黑书上面只是说了个大概的框架,李睿在2002年《二分法与统计问题》中也有提到,基本是差不多的,不再赘述。

    扫描线我就不多说了,主要是把扫描线扫描的点拆成两个事件点这个操作非常之牛逼。扩充为二维,则是把一个关于x的事件点拆成两个后,将关于y的事件点再拆成两个,先使得扫描线能后合理连续扫,故先让x排序,再把y的两个事件点用一颗静态二叉排序树来统计。

    统计分成三种:

    1、最大值在左树上 既 MAX[ lson(now) ]; (由于左子树的左半部分可能为最优值,而SUM[ lson(now) ]则可能小于MAX[ lson(now) ])

    2、最大值正好包含根结点 既 SUM[ now ] - SUM[ rson(now) ]; (若包含根,则左子树部分一定是SUM[ lson(now) ]为最优值)

    3、最大值在右树上 既 SUM[ now ] - SUM[ rson(now) ] + MAX[ rson(now) ];(由于在右子树上,又要求前k项的和,故右子树的最优值受到左子树和根节点的牵制)

    这道题要用到unique_copy,因为建树的时候要去掉重复的点,还有的就是要注意对于x相同的点,有可能是离去的,也有可能是进入的,则先要离去后进入。

    CODE:

 

静态排序二叉树静态排序二叉树代码
 1 #include <cstdio>
2 #include <iostream>
3 #include <algorithm>
4 using namespace std;
5
6 #define lson(x) (x << 1)
7 #define rson(x) (x << 1) + 1
8
9 typedef __int64 LL;
10
11 const int maxn = 1 << 20;
12 LL n, W, H, B[maxn], T[maxn], SUM[maxn], MAX[maxn];
13 struct NODE { LL x, y, c; } P[maxn];
14
15 bool operator < (const NODE x, const NODE y)
16 {
17 if(x.x == y.x)
18 return x.c < y.c;
19 return x.x < y.x;
20 }
21
22 void built(int now, int l, int r)
23 {
24 if(l == r)
25 return ;
26 int m = (l + r) >> 1;
27 T[ now ] = B[ m ];
28 built(lson(now), l, m);
29 built(rson(now), m + 1, r);
30 }
31
32 void insert(int now, LL key, LL delta)
33 {
34 while(T[now] != key) {
35 if(T[now] < key)
36 now = rson(now);
37 else
38 now = lson(now);
39 }
40 while(now) {
41 SUM[now] += delta;
42 MAX[now] = max(MAX[ lson(now) ] , SUM[now] - SUM[ rson(now) ]);
43 MAX[now] = max(MAX[now] , SUM[now] - SUM[ rson(now) ] + MAX[ rson(now) ]);
44 now >>= 1;
45 }
46 }
47
48 int main()
49 {
50 while(~scanf("%I64d %I64d %I64d", &n, &W, &H))
51 {
52 memset(SUM, 0, sizeof(SUM));
53 memset(MAX, 0, sizeof(MAX));
54 memset(T, 0, sizeof(T));
55 LL u, v, w;
56 int len = 0;
57 for(int i=0; i < n; i++) {
58 scanf("%I64d %I64d %I64d", &u, &v, &w);
59 P[i].x = u;
60 P[i].y = v;
61 P[i].c = w;
62 P[i + n].x = u + W;
63 P[i + n].y = v;
64 P[i + n].c = -w;
65 B[len ++] = P[i].y;
66 B[len ++] = P[i].y + H;
67 }
68 n <<= 1;
69 sort(P, P + n);
70 sort(B, B + len);
71 len = unique_copy(B, B + len, B) - B;
72 built(1 , 0 , len);
73 LL ans = 0;
74 for(int i=0; i < n; i++)
75 {
76 insert(1 , P[i].y , P[i].c);
77 insert(1 , P[i].y + H, -P[i].c);
78 ans = max(MAX[1] , ans);
79 }
80 printf("%I64d\n", ans);
81 }
82 return 0;
83 }
84

 

转载于:https://www.cnblogs.com/xiao_wu/archive/2010/05/19/1739192.html

上一篇:线段树推式子版


下一篇:未写完