码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3368 Frequent values(RMQ)

时间:2015-03-11 00:44:27      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:

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

也许看完题你可能想到了线段树做法,但是这道题的确可以用RMQ来写。

具体就是查询区间中重复最多的次数,但是RMQ只能查询区间最大值,我们

初始化的时候也只能初始化连续的那一部分,如果区间中不连续了了。

所以我们要在查询上下功夫。从查询左端点起,找到不连续的点pos,pos

以后的就可以RMQ查询,具体答案就是max(pos-l,RMQ(POS,l))

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
typedef long long LL;
typedef pair<int,int>pil;
const int INF = 0x3f3f3f3f;
const int maxn=1e5+100;
int num[maxn],sum[maxn];
int n,q;
int dp[maxn][20];
void init()
{
    REPF(i,1,n)
       dp[i][0]=sum[i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
           dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
int RMQ(int l,int r)
{
    int k=(int)(log(r-l+1)/log(2.0));
    return max(dp[l][k],dp[r-(1<<k)+1][k]);
}
void work()
{
    int x,y,ans;
    while(q--)
    {
        scanf("%d%d",&x,&y);
        int pos=x+1;
        while(num[pos]==num[pos-1]&&pos<=y)  pos++;
        if(pos>y) ans=pos-x;
        else ans=max(pos-x,RMQ(pos,y));
        printf("%d\n",ans);
    }
}
int main()
{
    int x;
    while(~scanf("%d",&n)&&n)
    {
        scanf("%d",&q);
        CLEAR(sum,0);num[0]=INF;
        REPF(i,1,n)
        {
            scanf("%d",&num[i]);
            if(num[i]==num[i-1])
                sum[i]=sum[i-1]+1;
            else sum[i]=1;
        }
        init();
        work();
    }
    return 0;
}


POJ 3368 Frequent values(RMQ)

标签:

原文地址:http://blog.csdn.net/u013582254/article/details/44186691

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!