POJ 3264

POJ: 3264

题目大意:给出n个数,给出一个区间[x,y],求这个区间的最大最小值。

解:可以用rmq的st算法,有空去切一下,这里用了线段树,入门,练习了构树和查询,不过自己对于左右端点的掌握还是需要犹豫。

看到别人写了一个树状数组的写法,挺神的,有空写下,刷刷排名。研究了一下,对于修改删除的题不适用,改过则必须重新初始化。或者自己写一个链表?可能可以对付删除情况?

线段树
 1 //poj 3264
2 const
3 maxn=51111;
4 inf='1.txt';
5 type
6 data=record
7 l, r, st, ed, mid, max, min: longint;
8 end;
9 var
10 tree: array[1..maxn*4]of data;
11 a: array[1..maxn]of longint;
12 ansmax, ansmin, n, q: longint;
13 procedure build(s, e, k: longint);
14 begin
15 with tree[k] do begin
16 min := maxlongint; max := 0;
17 st := s; ed := e;
18 mid := (s+e)>>1;
19 if s=e then begin
20 max := a[s]; min := a[s];
21 exit;
22 end;
23 l := k<<1; build(st, mid, l);
24 if min>tree[l].min then min := tree[l].min;
25 if max<tree[l].max then max := tree[l].max;
26 r := k<<1 + 1; build(mid+1, ed, r);
27 if min>tree[r].min then min := tree[r].min;
28 if max<tree[r].max then max := tree[r].max;
29 end;
30 end;
31
32 function askmin(s, e, k: longint): longint;
33 var
34 tmp: longint;
35 begin
36 askmin := maxlongint; tmp := maxlongint;
37 with tree[k] do begin
38 if (s<=st)and(ed<=e) then exit(tree[k].min);
39 if s<=mid then askmin := askmin(s, e, l);
40 if e>mid then tmp := askmin(s, e, r);
41 if tmp<askmin then askmin := tmp;
42 end;
43 end;
44
45 function askmax(s, e, k: longint): longint;
46 var
47 tmp: longint;
48 begin
49 askmax := 0; tmp := 0;
50 with tree[k] do begin
51 if (s<=st)and(ed<=e) then exit(tree[k].max);
52 if s<=mid then askmax := askmax(s, e, l);
53 if e>mid then tmp := askmax(s, e, r);
54 if tmp>askmax then askmax := tmp;
55 end;
56 end;
57
58 procedure init;
59 var
60 i: longint;
61 begin
62 readln(n, q);
63 for i := 1 to n do readln(a[i]);
64 build(1, n, 1);
65 end;
66
67 procedure main;
68 var
69 i, x, y: longint;
70 begin
71 for i := 1 to q do begin
72 readln(x, y);
73 writeln(askmax(x, y, 1)-askmin(x, y, 1));
74 end;
75 end;
76
77 begin
78 // assign(input,inf); reset(input);
79 init;
80 main;
81 end.



posted @ 2012-04-06 20:09  F.D.His.D  阅读(339)  评论(0编辑  收藏  举报