procedure2012
It's not worth it to know you're not worth it!

[题目来源]:Ulm Local 2007

[关键字]:RMQ

[题目大意]:给定一个非递减的整数序列(n),然后给出m个查询区间,针对每一个查询,输出此区间内重复最多的数字重复的次数。

//=====================================================================================================

[分析]:如果给定的区间恰好是连续的区间的两端则可直接同过RMQ问题求解。但如果不是这样则需要先求出两遍的最大值,再求中间就转换成了之前所说的问题。

[代码]:

View Code
 1 var
2 n, q: longint;
3 a, b, c: array[0..100100] of longint;
4 f: array[0..100100,0..40] of longint;
5
6 function max(x, y: longint):longint;
7 begin
8 if x > y then exit(x) else exit(y);
9 end;
10
11 procedure st;
12 var
13 t, i, j: longint;
14 begin
15 for i := 1 to n do f[i,0] := a[i];
16 t := trunc(ln(n)/ln(2));
17 for j := 1 to t do
18 for i := 1 to n+1-1 shl j do
19 f[i,j] := max(f[i,j-1],f[i+1 shl (j-1),j-1])
20 end;
21
22 procedure init;
23 var
24 i: longint;
25 begin
26 read(n);
27 if n = 0 then halt;
28 readln(q);
29 for i := 1 to n do
30 read(c[i]);
31 a[1] := 1;
32 for i := 2 to n do
33 if c[i] = c[i-1] then a[i] := a[i-1]+1 else a[i] := 1;
34 b[n] := a[n];
35 for i := n-1 downto 1 do
36 if c[i] = c[i+1] then b[i] := b[i+1] else b[i] := a[i];
37 fillchar(f,sizeof(f),0);
38 st;
39 end;
40
41 function find(x, y: longint):longint;
42 var
43 ans, t: longint;
44 begin
45 ans := b[x]-a[x]+1;
46 if ans < a[y] then ans := a[y];
47 if ans > y-x+1 then exit(y-x+1);
48
49 x := x+b[x]-a[x]+1;
50 y := y-a[y];
51 if x >= y then exit(ans);
52
53 t := trunc(ln(y-x+1)/ln(2));
54 ans := max(max(f[x,t],f[y-1 shl t+1,t]),ans);
55
56 exit(ans);
57 end;
58
59 procedure work;
60 var
61 i, ans, x ,y: longint;
62 begin
63 for i := 1 to q do
64 begin
65 readln(x,y);
66 ans := find(x,y);
67 writeln(ans);
68 end;
69 end;
70
71 begin
72 while 1 = 1 do
73 begin
74 init;
75 work;
76 end;
77 end.



posted on 2011-11-02 16:06  procedure2012  阅读(248)  评论(0编辑  收藏  举报