【问题描述】
 

  老管家是一个聪明能干的人。他为财主工作了整整10年,财主为了让自已账目更加清楚。要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意。但是由于一些人的挑拨,财主还是对管家产生了怀疑。于是他决定用一种特别的方法来判断管家的忠诚,他把每次的账目按1,2,3…编号,然后不定时的问管家问题,问题是这样的:在a到b号账中最少的一笔是多少?为了让管家没时间作假他总是一次问多个问题。

 

【解题报告】

RMQ问题,用线段树或者ST(后者速度快点,本菜用的前者)。

线段树嘛,数组开大点(至少是N的两倍嘛)。

 1 program tyvj1038;
2
3 type
4 arr=record
5 a,b,l,r,min:longint;
6 end;
7
8 var
9 x,y,tt,n,m,i:longint;
10 tree:array[1..1000001]of arr;
11
12 function min(a,b:longint):longint;
13 begin
14 if a<b then exit(a);
15 exit(b);
16 end;
17
18 procedure buildtree(l,r:longint);
19 var
20 now:longint;
21 begin
22 inc(tt);
23 now:=tt;
24 tree[now].a:=l;
25 tree[now].b:=r;
26 tree[now].min:=maxlongint;
27 if l+1<r then
28 begin
29 tree[now].l:=tt+1;
30 buildtree(l,(l+r)div 2);
31 tree[now].r:=tt+1;
32 buildtree((l+r)div 2,r);
33 end;
34 end;
35
36 procedure add(tmep,x,y,t:longint);
37 begin
38 tree[tmep].min:=min(tree[tmep].min,t);
39 if tree[tmep].a+1>=tree[tmep].b then exit;
40 if y<=(tree[tmep].a+tree[tmep].b)div 2 then add(tree[tmep].l,x,y,t)
41 else add(tree[tmep].r,x,y,t);
42 end;
43
44 function getmin(sum,x,y:longint):longint;
45 begin
46 if (x>=tree[sum].b)or(y<=tree[sum].a) then exit(maxlongint);
47 if (x<=tree[sum].a)and(y>=tree[sum].b)then exit(tree[sum].min);
48 exit(min(getmin(tree[sum].l,x,y),getmin(tree[sum].r,x,y)));
49 end;
50
51 procedure main;
52 begin
53 readln(n,m);
54 tt:=0;
55 buildtree(1,n+1);
56 for i:=1 to n do
57 begin
58 read(x);
59 add(1,i,i+1,x);
60 end;
61 for i:=1 to m-1 do
62 begin
63 readln(x,y);
64 write(getmin(1,x,y+1),' ');
65 end;
66 readln(x,y);
67 writeln(getmin(1,x,y+1));
68 end;
69
70 begin
71 main;
72 end.