您的位置:首页 > 产品设计 > UI/UE

[RMQ]Pku3368-Frequent values

2010-02-01 15:03 218 查看
http://acm.pku.edu.cn/JudgeOnline/problem?id=3368

Frequent values

Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 4431Accepted: 1554
Description

You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , ... , aj.

Input

The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains n integers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The following q lines contain one query each, consisting of two integers i and j (1 ≤ i ≤ j ≤ n), which indicate the boundary indices for the
query.

The last test case is followed by a line containing a single 0.

Output

For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.

Sample Input
10 3
-1 -1 1 1 1 1 3 10 10 10
2 3
1 10
5 10
0

Sample Output
1
4
3

Source
Ulm Local 2007

题目大意:给出一个不下降序列,要求回答若干个询问:对于区间[i,j],出现频率最高的数字出现的频率是多少。

分析:作为一个区间询问问题,不难想到用线段树去做,也确实可行。我用了rmq。用next数组来记录每个数向前和向后能延伸到那里,就不难使用rmq解决这个问题了。

codes:

const
h:array[0..16]of longint=(1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536);
var
n,q,len,ans:longint;
a,next,next1:array[0..100001]of longint;
b:array[0..100001,0..20]of longint;
function max(x,y:longint):longint;
begin
if x>y then exit(x)
else exit(y);
end;
procedure work;
var
i,j,x,y,t1,t2:longint;
begin
repeat
fillchar(a,sizeof(a),0);
fillchar(b,sizeof(b),0);
fillchar(next,sizeof(next),0);
fillchar(next1,sizeof(next1),0);
read(n);
if n=0 then break;
read(q);
a[0]:=-200000;
for i:=1 to n do
begin
read(a[i]);
if a[i]=a[i-1] then next[i]:=next[i-1]
else next[i]:=i;
end;
a[n+1]:=200000;
for i:=n downto 1 do
begin
if a[i]=a[i+1] then next1[i]:=next1[i+1]
else next1[i]:=i;
end;
len:=trunc(ln(n)/ln(2));
for i:=1 to n do
b[i,0]:=1;
for i:=1 to len do
begin
for j:=1 to n-h[i]+1 do
begin
b[j,i]:=max(b[j,i-1],b[j+h[i-1],i-1]);
if a[j+h[i-1]-1]=a[j+h[i-1]] then
begin
t1:=next[j+h[i-1]-1];
t2:=next1[j+h[i-1]];
if t1<j then t1:=j;
if t2>j+h[i]-1 then t2:=j+h[i]-1;
if t2-t1+1>b[j,i] then b[j,i]:=t2-t1+1;
end;
end;
end;
for i:=1 to q do
begin
readln(x,y);
len:=trunc(ln(y-x+1)/ln(2));
ans:=max(b[x,len],b[y-h[len]+1,len]);
if a[x+h[len]-1]=a[y-h[len]+1] then
begin
t1:=next[x+h[len]-1];
t2:=next1[y-h[len]+1];
if t1<x then t1:=x;
if t2>y then t2:=y;
if t2-t1+1>ans then ans:=t2-t1+1;
end;
writeln(ans);
end;
until false;
end;
begin
work;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: