POJ 3368 Frequent values

洛谷 UVA11235

https://www.luogu.org/problemnew/show/UVA11235

洛谷 SP1684

https://www.luogu.org/problemnew/show/SP1684

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

真的是好奇怪鸭!一模一样的题,竟然一道是蓝题一道是紫题。。。不过我就不要脸..咳咳,不客气地全切了。
一开始只能想到暴力,但是TLE没跑了,所以就开始开发更优地解法,看过洛谷的题解后想到了RMQ的一种变形。
是的,一开始我的思路也被限制住了,RMQ不是区间求最值么?什么时候可以求元素出现次数了?
这么想的我说明自己还是个弱鸡。
这道题的RMQ比较难想,这里的f数组表示的是从i开始的2^j个元素中重复最多的次数,注意是次数。
这里我们还需要注意处理一下左右端点,因为可能会出现答案存在的区间横跨中间点的情况出现,所以要在询问出解的时候特殊判定一下。
不多说了,我觉得这道题够一道紫题,毕竟这真的是我自己A的第一道紫题哈哈哈哈
AC c o d e:
#include<cstdio>
#include<cmath>
#include<iostream>
#define N 100001
using namespace std;
int n,q,a[N],dp[N],f[N][17],lg[N];
int ask(int l,int r)
{
    if(l>r)
        return 0;
    int k=lg[r-l+1];
    return max(f[l][k],f[r-(1<<k)+1][k]);
}
int main()
{
    while(~scanf("%d%d",&n,&q)&&n)
    {
        dp[1]=1;
        for(int i=2;i<=n;i++)
            lg[i]=lg[i>>1]+1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(i>1) 
            {
                if(a[i]==a[i-1])
                    dp[i]=dp[i-1]+1;
                else
                    dp[i]=1;
            }
        }
        for(int i=1;i<=n;i++)
            f[i][0]=dp[i];
        for(int j=1;(1<<j)<=n;j++)
            for(int i=1;i+(1<<j)-1<=n;i++)
                f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
        while(q--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            int now=l;
            while(now<=r && a[now]==a[now-1])
                now++;
            printf("%d\n",max(now-l,ask(now,r)));
        }
    }
}

 

posted @ 2019-07-12 19:35  Seaway-Fu  阅读(169)  评论(0编辑  收藏  举报