[PKU 1177 3277] 线段树(二) {离散化 矩形并问题}

{

承上篇

这次的代码是好久以前写的

感觉比较乱 将就看看吧

这里介绍线段树的删除和一些其他技巧

以求矩形并的周长和面积为例

}

 

上次讨论了利用线段树解决涂色的问题

有一个问题遗留下来

如果我要擦除颜色 该怎么做呢?

很简单 只要插入颜色为0的线段就可以了

因为这里的插入是覆盖型

任何一个区间只有一个颜色 要擦也是一起擦干净

也就是一个节点上至多只被盖着一条线段 以前的线段会被新来的取代

所以这是一个特殊的问题

更为一般的问题是 一个节点上可以有多条线段 互不干涉 地位平等

在线段树上插入若干这样的线段之后

我们还要执行 删除 统计(测度 连续段数等) 操作

 

先看一个具体问题 PKU 1177

http://poj.org/problem?id=1177

不过 我们把矩形的坐标范围提升至100w 矩形个数为10w

题意很简单 给定若干个矩形 求矩形周长并

先看图

[PKU 1177 3277] 线段树(二) {离散化 矩形并问题}

为了解决这个问题 我们先把一坨一坨的矩形 进行矩形切割

[PKU 1177 3277] 线段树(二) {离散化 矩形并问题}

[PKU 1177 3277] 线段树(二) {离散化 矩形并问题}[PKU 1177 3277] 线段树(二) {离散化 矩形并问题}

 

我们考虑周长由哪些部分构成

其中 红线是需要统计入周长的竖边 绿线是需要统计入周长的横边

我们称两条蓝线之间的部分为统计区间

我们需要依次统计从左到右的统计区间内的需要计数的矩形边 累加

形象地讲 就是用一根扫描线 从左到右依次扫描

具体实现就是依次遍历那些蓝线然后 累加每个区间的统计结果

  我们任取2个统计区间进行详细讨论 放大前2个统计区间部分

[PKU 1177 3277] 线段树(二) {离散化 矩形并问题}

考虑为什么同样是矩形边 红边需要统计而深红色的边不需要统计

我们发现深红色的边包含在第一个矩形内部 也就是夹在第一个矩形两条边之间

继续分析 我们可以知道 横边也是这样

深蓝色边加在统计区间内的两条绿色边之间 属于矩形内部 不需要统计

那么 如何判定是否是红边或绿边呢?

我们在扫描线上投下当前经过扫描线矩形的投影

[PKU 1177 3277] 线段树(二) {离散化 矩形并问题}

 

红边必然造成投影的变化 绿边必然在投影上线段的端点处

没有造成投影变化的竖边 肯定在投影内部 也就是在还未扫描完的矩形内部

[PKU 1177 3277] 线段树(二) {离散化 矩形并问题}

不在投影线段段端点处的横边 也会夹在在投影线段端点处的两个矩形边内

[PKU 1177 3277] 线段树(二) {离散化 矩形并问题}

于是 我们将绿边的长度=统计区间宽*投影连续段数*2

再与红边的长度=与上一个区间投影的差求和 即得到当前区间的统计值 再累加即可

至此 我们只要了解扫描到的矩形的投影的段数N()和总长度M()即可

 

——利用线段树解决这个问题

扫描线从左到右扫描矩形

用线段树记录下扫描线上的投影的情况

当扫描线碰到举行左边的时候就插入这个线段 碰到矩形右边就删除这个线段

用线段树统计出扫描线上的投影的信息

 我们还要重新规划在线段树上的域 除了只有ls[] rs[] l[] r[]需要保留外

我们要添加新的域 覆盖次数cover[] 连续段数ls[] 测度m[](即被覆盖的总长度)

这几个域需要我们实时维护 更需增加维护ls[]的域 lb[] rb[]表示左右端点是否被覆盖

 

介绍一下具体的做法

*事件排序&离散化

 

  
    
1 procedure sorty(l,r:longint);
2   var i,j,temp,mid:longint;
3   begin
4 mid: = y[(l + r)shr 1 ];
5 i: = l; j: = r;
6   repeat
7   while y[i] < mid do inc(i);
8   while mid < y[j] do dec(j);
9   if not (i > j)
10 then begin
11 temp: = y[i];
12 y[i]: = y[j];
13 y[j]: = temp;
14 inc(i); dec(j);
15 end ;
16   until i > j;
17   if i < r then sorty(i,r);
18   if l < j then sorty(l,j);
19   end ;
20   function find(x:longint):longint;
21   var l,r,mid:longint;
22   begin
23 l: = 1 ; r: = t;
24   while l <= r do
25 begin
26 mid: = (l + r)shr 1 ;
27 if x < y[mid] then r: = mid - 1
28 else if y[mid] < x then l: = mid + 1
29 else begin find: = mid; exit; end ;
30 end ;
31   end ;
32   procedure sortindex(l,r:longint);
33   var i,j,temp,mid1,mid2:longint;
34   begin
35 mid1: = index[(l + r)shr 1 ].x;
36 mid2: = index[(l + r)shr 1 ].flag;
37 i: = l; j: = r;
38   repeat
39   while (index[i].x < mid1) or ((index[i].x = mid1) and (index[i].flag < mid2)) do inc(i);
40   while (mid1 < index[j].x) or ((mid1 = index[j].x) and (mid2 < index[j].flag)) do dec(j);
41 if not (i > j)
42 then begin
43 if (index[j].x < index[i].x) or ((index[j].x = index[i].x) and (index[j].flag < index[i].flag))
44 then begin
45 temp: = index[i].x;
46 index[i].x: = index[j].x;
47 index[j].x: = temp;
48 temp: = index[i].y1;
49 index[i].y1: = index[j].y1;
50 index[j].y1: = temp;
51 temp: = index[i].y2;
52 index[i].y2: = index[j].y2;
53 index[j].y2: = temp;
54 temp: = index[i].flag;
55 index[i].flag: = index[j].flag;
56 index[j].flag: = temp;
57 end ;
58 inc(i); dec(j);
59 end ;
60 until i > j;
61 if i < r then sortindex(i,r);
62 if l < j then sortindex(l,j);
63 end ;

 

 

 

  
    
1 readln(n);
2 t: = 0 ;
3 for i: = 1 to n do
4 begin
5 readln(x1[i],y1[i],x2[i],y2[i]);
6 inc(t); y[t]: = y1[i];
7 inc(t); y[t]: = y2[i];
8 end ;
9 sorty( 1 ,t);
10 for i: = 1 to n do
11 begin
12 y1[i]: = find(y1[i]);
13 y2[i]: = find(y2[i]);
14 end ;
15 t: = 0 ;
16 for i: = 1 to n do
17 begin
18 inc(t);
19 index[t].x: = x1[i];
20 index[t].y1: = y1[i];
21 index[t].y2: = y2[i];
22 index[t].flag: =- 1 ;
23 inc(t);
24 index[t].x: = x2[i];
25 index[t].y1: = y1[i];
26 index[t].y2: = y2[i];
27 index[t].flag: = 1 ;
28 end ;
29 sortindex( 1 ,t);

 

 

  +这是为了能够从左到右扫描

  +由于数据范围有100w 我们需要离散化

    -主程序里1-14行运用快速排序和二分查找将纵坐标坐标离散成数组下标即可

    -排序之后 数组下标可以反映坐标大小 这就是我们需要的离散信息

    -但是我们得记录下原来的值 因为还要统计线段长度

  +称插入或删除一条线段为一个事件 15-29行把所有事件保存起来然后排序

    -注意用flag表示是插入还是删除 如果横坐标相同 先插入后删除

*建树

  +注意建线段树的范围 不是[-100w,100w] 是[0,n]了

*扫描统计

  +插入

 

  
    
1 procedure insert(x,a,b:longint);
2 var mid:longint;
3 begin
4 if (a <= tree[x].l) and (tree[x].r <= b)
5 then inc(tree[x].cover)
6 else begin
7 mid: = (tree[x].l + tree[x].r)shr 1 ;
8 if a < mid then insert(tree[x].lc,a,b);
9 if mid < b then insert(tree[x].rc,a,b);
10 end ;
11 if tree[x].cover > 0
12 then begin
13 tree[x].m: = y[tree[x].r] - y[tree[x].l];
14 tree[x].lb: = 1 ; tree[x].rb: = 1 ;
15 tree[x].ls: = 1 ;
16 end
17 else if (tree[x].cover = 0 ) and (tree[x].r - tree[x].l = 1 )
18 then begin
19 tree[x].m: = 0 ;
20 tree[x].lb: = 0 ; tree[x].rb: = 0 ;
21 tree[x].ls: = 0 ;
22 end
23 else begin
24 tree[x].m: = tree[tree[x].lc].m + tree[tree[x].rc].m;
25 tree[x].lb: = tree[tree[x].lc].lb; tree[x].rb: = tree[tree[x].rc].rb;
26 if (tree[tree[x].lc].rb = 1 ) and (tree[tree[x].rc].lb = 1 )
27 then tree[x].ls: = tree[tree[x].lc].ls + tree[tree[x].rc].ls - 1
28 else tree[x].ls: = tree[tree[x].lc].ls + tree[tree[x].rc].ls;
29 end ;
30 end ;

 

    -(以前的代码 感觉很难看...)

 

    -第4-10行 插入线段的基本语句 具体解释见线段树(一)

    -第11-30行 更新数据域 实质上可以新写一个函数来实现了

      ~前面11-22行判断是否直接赋值

      ~第26-29行分类讨论 lb[] rb[]是否同时为1 判断连续段数的改变

      ~第24行测度直接由儿子更新 求和 25行lb[] rb[]也直接更新即可

  +删除 这里的删除保证以前插入过这条线段

 

  
    
1 procedure delete(x,a,b:longint);
2 var mid:longint;
3 begin
4 if (a <= tree[x].l) and (tree[x].r <= b)
5 then dec(tree[x].cover)
6 else begin
7 mid: = (tree[x].l + tree[x].r)shr 1 ;
8 if a < mid then delete(tree[x].lc,a,b);
9 if mid < b then delete(tree[x].rc,a,b);
10 end ;
11 if tree[x].cover > 0
12 then begin
13 tree[x].m: = y[tree[x].r] - y[tree[x].l];
14 tree[x].lb: = 1 ; tree[x].rb: = 1 ;
15 tree[x].ls: = 1 ;
16 end
17 else if (tree[x].cover = 0 ) and (tree[x].r - tree[x].l = 1 )
18 then begin
19 tree[x].m: = 0 ;
20 tree[x].lb: = 0 ; tree[x].rb: = 0 ;
21 tree[x].ls: = 0 ;
22 end
23 else begin
24 tree[x].m: = tree[tree[x].lc].m + tree[tree[x].rc].m;
25 tree[x].lb: = tree[tree[x].lc].lb; tree[x].rb: = tree[tree[x].rc].rb;
26 if (tree[tree[x].lc].rb = 1 ) and (tree[tree[x].rc].lb = 1 )
27 then tree[x].ls: = tree[tree[x].lc].ls + tree[tree[x].rc].ls - 1
28 else tree[x].ls: = tree[tree[x].lc].ls + tree[tree[x].rc].ls;
29 end ;
30 end ;

 

 

    -所以只要改一改插入

  +统计 根据根节点的测度和连续段数 得出统计值累加

 

  
    
1 ans: = 0 ;
2 last: = 0 ;
3 index[t + 1 ].x: = index[t].x;
4 for i: = 1 to t do
5 begin
6 if index[i].flag =- 1
7 then insert( 1 ,index[i].y1,index[i].y2)
8 else delete( 1 ,index[i].y1,index[i].y2);
9 temp: = index[i + 1 ].x - index[i].x;
10 temp: = temp + temp;
11 temp: = temp * tree[ 1 ].ls;
12 temp: = temp + abs(tree[ 1 ].m - last);
13 ans: = ans + temp;
14 last: = tree[ 1 ].m;
15 end ;
16 writeln(ans);

    -运用公式求值

 

这样我们就把求矩形周长并解决了

求矩形面积并更加简单 利用测度即可

问题来源是PKU 3277

两个程序的代码

 

  
    
1 { 6955221 Master_Chivu 1177 Accepted 1948K 32MS Pascal 4579B 2010-05-24 00:06:55 }
2 const maxl = 100000 ;maxn = 100000 ;
3 type
4 treenode =
5 record
6 l,r:longint;
7 ls,lb,rb,m,cover:longint;
8 lc,rc:longint;
9 end ;
10 var tree: array [ 1 ..maxl shl 1 - 1 ] of treenode;
11 x1,x2,y1,y2: array [ 1 ..maxn] of longint;
12 y: array [ 1 ..maxn shl 1 ] of longint;
13 index: array [ 1 ..maxn shl 1 ] of record x,y1,y2,flag:longint; end ;
14 ans,temp:int64;
15 n,t,i,tot,last:longint;
16 procedure sorty(l,r:longint);
17 var i,j,temp,mid:longint;
18 begin
19 mid: = y[(l + r)shr 1 ];
20 i: = l; j: = r;
21 repeat
22 while y[i] < mid do inc(i);
23 while mid < y[j] do dec(j);
24 if not (i > j)
25 then begin
26 temp: = y[i];
27 y[i]: = y[j];
28 y[j]: = temp;
29 inc(i); dec(j);
30 end ;
31 until i > j;
32 if i < r then sorty(i,r);
33 if l < j then sorty(l,j);
34 end ;
35 function find(x:longint):longint;
36 var l,r,mid:longint;
37 begin
38 l: = 1 ; r: = t;
39 while l <= r do
40 begin
41 mid: = (l + r)shr 1 ;
42 if x < y[mid] then r: = mid - 1
43 else if y[mid] < x then l: = mid + 1
44 else begin find: = mid; exit; end ;
45 end ;
46 end ;
47 procedure sortindex(l,r:longint);
48 var i,j,temp,mid1,mid2:longint;
49 begin
50 mid1: = index[(l + r)shr 1 ].x;
51 mid2: = index[(l + r)shr 1 ].flag;
52 i: = l; j: = r;
53 repeat
54 while (index[i].x < mid1) or ((index[i].x = mid1) and (index[i].flag < mid2)) do inc(i);
55 while (mid1 < index[j].x) or ((mid1 = index[j].x) and (mid2 < index[j].flag)) do dec(j);
56 if not (i > j)
57 then begin
58 if (index[j].x < index[i].x) or ((index[j].x = index[i].x) and (index[j].flag < index[i].flag))
59 then begin
60 temp: = index[i].x;
61 index[i].x: = index[j].x;
62 index[j].x: = temp;
63 temp: = index[i].y1;
64 index[i].y1: = index[j].y1;
65 index[j].y1: = temp;
66 temp: = index[i].y2;
67 index[i].y2: = index[j].y2;
68 index[j].y2: = temp;
69 temp: = index[i].flag;
70 index[i].flag: = index[j].flag;
71 index[j].flag: = temp;
72 end ;
73 inc(i); dec(j);
74 end ;
75 until i > j;
76 if i < r then sortindex(i,r);
77 if l < j then sortindex(l,j);
78 end ;
79 procedure build(a,b:longint);
80 var mid,now:longint;
81 begin
82 inc(tot);
83 now: = tot;
84 tree[now].l: = a;
85 tree[now].r: = b;
86 if b - a > 1
87 then begin
88 mid: = (a + b)shr 1 ;
89 tree[now].lc: = tot + 1 ;
90 build(a,mid);
91 tree[now].rc: = tot + 1 ;
92 build(mid,b);
93 end ;
94 end ;
95 procedure insert(x,a,b:longint);
96 var mid:longint;
97 begin
98 if (a <= tree[x].l) and (tree[x].r <= b)
99 then inc(tree[x].cover)
100 else begin
101 mid: = (tree[x].l + tree[x].r)shr 1 ;
102 if a < mid then insert(tree[x].lc,a,b);
103 if mid < b then insert(tree[x].rc,a,b);
104 end ;
105 if tree[x].cover > 0
106 then begin
107 tree[x].m: = y[tree[x].r] - y[tree[x].l];
108 tree[x].lb: = 1 ; tree[x].rb: = 1 ;
109 tree[x].ls: = 1 ;
110 end
111 else if (tree[x].cover = 0 ) and (tree[x].r - tree[x].l = 1 )
112 then begin
113 tree[x].m: = 0 ;
114 tree[x].lb: = 0 ; tree[x].rb: = 0 ;
115 tree[x].ls: = 0 ;
116 end
117 else begin
118 tree[x].m: = tree[tree[x].lc].m + tree[tree[x].rc].m;
119 tree[x].lb: = tree[tree[x].lc].lb; tree[x].rb: = tree[tree[x].rc].rb;
120 if (tree[tree[x].lc].rb = 1 ) and (tree[tree[x].rc].lb = 1 )
121 then tree[x].ls: = tree[tree[x].lc].ls + tree[tree[x].rc].ls - 1
122 else tree[x].ls: = tree[tree[x].lc].ls + tree[tree[x].rc].ls;
123 end ;
124 end ;
125 procedure delete(x,a,b:longint);
126 var mid:longint;
127 begin
128 if (a <= tree[x].l) and (tree[x].r <= b)
129 then dec(tree[x].cover)
130 else begin
131 mid: = (tree[x].l + tree[x].r)shr 1 ;
132 if a < mid then delete(tree[x].lc,a,b);
133 if mid < b then delete(tree[x].rc,a,b);
134 end ;
135 if tree[x].cover > 0
136 then begin
137 tree[x].m: = y[tree[x].r] - y[tree[x].l];
138 tree[x].lb: = 1 ; tree[x].rb: = 1 ;
139 tree[x].ls: = 1 ;
140 end
141 else if (tree[x].cover = 0 ) and (tree[x].r - tree[x].l = 1 )
142 then begin
143 tree[x].m: = 0 ;
144 tree[x].lb: = 0 ; tree[x].rb: = 0 ;
145 tree[x].ls: = 0 ;
146 end
147 else begin
148 tree[x].m: = tree[tree[x].lc].m + tree[tree[x].rc].m;
149 tree[x].lb: = tree[tree[x].lc].lb; tree[x].rb: = tree[tree[x].rc].rb;
150 if (tree[tree[x].lc].rb = 1 ) and (tree[tree[x].rc].lb = 1 )
151 then tree[x].ls: = tree[tree[x].lc].ls + tree[tree[x].rc].ls - 1
152 else tree[x].ls: = tree[tree[x].lc].ls + tree[tree[x].rc].ls;
153 end ;
154 end ;
155 begin
156 assign(input, ' picture.in ' );
157 reset(input);
158 assign(output, ' picture.out ' );
159 rewrite(output);
160 readln(n);
161 t: = 0 ;
162 for i: = 1 to n do
163 begin
164 readln(x1[i],y1[i],x2[i],y2[i]);
165 inc(t); y[t]: = y1[i];
166 inc(t); y[t]: = y2[i];
167 end ;
168 sorty( 1 ,t);
169 for i: = 1 to n do
170 begin
171 y1[i]: = find(y1[i]);
172 y2[i]: = find(y2[i]);
173 end ;
174 t: = 0 ;
175 for i: = 1 to n do
176 begin
177 inc(t);
178 index[t].x: = x1[i];
179 index[t].y1: = y1[i];
180 index[t].y2: = y2[i];
181 index[t].flag: =- 1 ;
182 inc(t);
183 index[t].x: = x2[i];
184 index[t].y1: = y1[i];
185 index[t].y2: = y2[i];
186 index[t].flag: = 1 ;
187 end ;
188 sortindex( 1 ,t);
189 tot: = 0 ;
190 build( 0 ,t);
191 ans: = 0 ;
192 last: = 0 ;
193 index[t + 1 ].x: = index[t].x;
194 for i: = 1 to t do
195 begin
196 if index[i].flag =- 1
197 then insert( 1 ,index[i].y1,index[i].y2)
198 else delete( 1 ,index[i].y1,index[i].y2);
199 temp: = index[i + 1 ].x - index[i].x;
200 temp: = temp + temp;
201 temp: = temp * tree[ 1 ].ls;
202 temp: = temp + abs(tree[ 1 ].m - last);
203 ans: = ans + temp;
204 last: = tree[ 1 ].m;
205 end ;
206 writeln(ans);
207 close(input);
208 close(output);
209 end .
210
  
    
1 { 6954141 Master_Chivu 3277 Accepted 4112K 704MS Pascal 3486B 2010-05-23 20:50:27 }
2 const maxl = 50000 ; maxn = 50000 ;
3 type
4 treenode =
5 record
6 l,r:longint;
7 cover:longint;
8 lc,rc:longint;
9 end ;
10 var tree: array [ 1 ..maxl shl 1 - 1 ] of treenode;
11 index: array [ 1 ..maxn shl 1 ] of record a,w,flag:longint; end ;
12 a,b,w: array [ 1 ..maxn] of longint;
13 h: array [ 0 ..maxn] of longint;
14 tot,n,i,t:longint; ans,temp:int64;
15 procedure sorth(l,r:longint);
16 var i,j,x,y:longint;
17 begin
18 x: = h[(l + r)shr 1 ];
19 i: = l; j: = r;
20 repeat
21 while h[i] < x do inc(i);
22 while x < h[j] do dec(j);
23 if not (i > j)
24 then begin
25 y: = h[i];
26 h[i]: = h[j];
27 h[j]: = y;
28 inc(i); dec(j);
29 end ;
30 until i > j;
31 if i < r then sorth(i,r);
32 if l < j then sorth(l,j);
33 end ;
34 function find(x:longint):longint;
35 var l,r,mid:longint;
36 begin
37 l: = 1 ; r: = n;
38 while l <= r do
39 begin
40 mid: = (l + r)shr 1 ;
41 if h[mid] < x then l: = mid + 1
42 else if h[mid] > x then r: = mid - 1
43 else begin find: = mid; exit; end ;
44 end ;
45 end ;
46 procedure sortindex(l,r:longint);
47 var i,j,x1,x2,y:longint;
48 begin
49 x1: = index[(l + r)shr 1 ].a;
50 x2: = index[(l + r)shr 1 ].flag;
51 i: = l; j: = r;
52 repeat
53 while (index[i].a < x1) or ((index[i].a = x1) and (index[i].flag < x2)) do inc(i);
54 while (x1 < index[j].a) or ((x1 = index[j].a) and (x2 < index[j].flag)) do dec(j);
55 if not (i > j)
56 then begin
57 if (index[i].a > index[j].a)
58 or ((index[i].a = index[j].a) and (index[i].flag > index[j].flag))
59 then begin
60 y: = index[i].a;
61 index[i].a: = index[j].a;
62 index[j].a: = y;
63 y: = index[i].w;
64 index[i].w: = index[j].w;
65 index[j].w: = y;
66 y: = index[i].flag;
67 index[i].flag: = index[j].flag;
68 index[j].flag: = y;
69 end ;
70 inc(i); dec(j);
71 end ;
72 until i > j;
73 if i < r then sortindex(i,r);
74 if l < j then sortindex(l,j);
75 end ;
76 procedure build(a,b:longint);
77 var mid,now:longint;
78 begin
79 inc(tot);
80 now: = tot;
81 tree[now].l: = a;
82 tree[now].r: = b;
83 if b - a > 1
84 then begin
85 mid: = (a + b)shr 1 ;
86 tree[now].lc: = tot + 1 ;
87 build(a,mid);
88 tree[now].rc: = tot + 1 ;
89 build(mid,b);
90 end ;
91 end ;
92 procedure insert(x,a,b:longint);
93 var mid:longint;
94 begin
95 if (a <= tree[x].l) and (tree[x].r <= b)
96 then begin
97 inc(tree[x].cover);
98 exit; end ;
99 mid: = (tree[x].l + tree[x].r)shr 1 ;
100 if a < mid then insert(tree[x].lc,a,b);
101 if mid < b then insert(tree[x].rc,a,b);
102 end ;
103 procedure delete(x,a,b:longint);
104 var mid:longint;
105 begin
106 if (a <= tree[x].l) and (tree[x].r <= b)
107 then begin
108 dec(tree[x].cover);
109 exit; end ;
110 mid: = (tree[x].l + tree[x].r)shr 1 ;
111 if a < mid then delete(tree[x].lc,a,b);
112 if mid < b then delete(tree[x].rc,a,b);
113 end ;
114 function count(x:longint):longint;
115 var ans:longint;
116 begin
117 if tree[x].cover > 0
118 then begin
119 count: = h[tree[x].r] - h[tree[x].l];
120 exit; end
121 else begin
122 ans: = 0 ;
123 if tree[x].lc <> 0 then ans: = ans + count(tree[x].lc);
124 if tree[x].rc <> 0 then ans: = ans + count(tree[x].rc);
125 count: = ans; end ;
126 end ;
127 begin
128 assign(input, ' rectangle.in ' );
129 reset(input);
130 assign(output, ' rectangle.out ' );
131 rewrite(output);
132 readln(n);
133 for i: = 1 to n do
134 begin
135 readln(a[i],b[i],w[i]);
136 h[i]: = w[i];
137 end ;
138 sorth( 1 ,n);
139 for i: = 1 to n do
140 w[i]: = find(w[i]);
141 t: = 0 ;
142 for i: = 1 to n do
143 begin
144 inc(t); index[t].a: = a[i]; index[t].w: = w[i]; index[t].flag: = 1 ;
145 inc(t); index[t].a: = b[i]; index[t].w: = w[i]; index[t].flag: =- 1 ;
146 end ;
147 sortindex( 1 ,t);
148 tot: = 0 ;
149 build( 0 ,n);
150 ans: = 0 ;
151 index[t + 1 ].a: = index[t].a;
152 for i: = 1 to t do
153 begin
154 if index[i].flag = 1
155 then insert( 1 , 0 ,index[i].w)
156 else delete( 1 , 0 ,index[i].w);
157 temp: = index[i + 1 ].a - index[i].a;
158 temp: = temp * count( 1 );
159 ans: = ans + temp;
160 end ;
161 writeln(ans);
162 close(input);
163 close(output);
164 end .
165

 

这个问题还是推荐去读一下 陈宏大神的论文

下一篇讨论牛B的Lazy-tag思想

 

Bob HAN 原创 转载请注明出处 http://www.cnblogs.com/Booble/

你可能感兴趣的:(线段树)