您的位置:首页 > 其它

poj 3368(RMQ应用)

2011-09-15 21:05 357 查看
Frequent values

Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 8555Accepted: 3081
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 integersa1 , ... , 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 qlines 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

题目:http://poj.org/problem?id=3368

分析:这题要求最长连续的数字。。。本来以为是出现次数最多,直接不会做阿。。。连续的话,就能转化为RMQ问题来搞

首先开一个数组a记录从左边到他本身有多少个连续的数,另一个数组b记录第i个数有几个和他相邻(待会计算位置用)

对于区间[l,r]

1.如果有a[r]>=r-l+1 即整个区间的数一样,直接返回区间长度

2.此时答案在左边,右边,和中间

左边 b[l]-a[l]+1

右边 a[r]

中间 取区间 [l+b[l]-a[l]+1,r-a[r]]的最大值(用ST算法预处理)

代码:

#include<iostream>
#include<cstdio>
using namespace std;
const int mm=111111;
int f[mm][22],a[mm],b[mm],c[mm];
int i,j,k,n,q;
void dp()
{
    for(i=1;i<=n;++i)f[i][0]=a[i];
    for(j=1;(1<<j)<=n;++j)
        for(i=1;i+(1<<j)-1<=n;++i)
            f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
int get(int l,int r)
{
    if(a[r]>=r-l+1)return r-l+1;
    int m=max(b[l]-a[l]+1,a[r]),k=0;
    l=l+b[l]-a[l]+1,r-=a[r];
    if(l>r)return m;
    while(l+(1<<k)<r-(1<<k)+1)++k;
    return max(m,max(f[l][k],f[r-(1<<k)+1][k]));
}
int main()
{
    while(scanf("%d",&n),n)
    {
        scanf("%d",&q);
        for(i=1;i<=n;++i)scanf("%d",&c[i]),a[i]=1;
        for(i=2;i<=n;++i)
            if(c[i-1]==c[i])a[i]+=a[i-1];
        for(b
=a
,i=n-1;i>0;--i)
            if(c[i+1]==c[i])b[i]=b[i+1];
            else b[i]=a[i];
        dp();
        while(q--)scanf("%d%d",&i,&j),printf("%d\n",get(i,j));
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: