Frequent values--RMQ

来源:互联网 发布:主机监控软件 编辑:程序博客网 时间:2024/05/21 19:29

Frequent values
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 17684 Accepted: 6372

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 102 31 105 100

Sample Output

143

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


RMQ进阶题目,对于RMQ我的上一篇博客有所讲解。


这个题的题意是有一段序列,有Q次查询,对于每次查询,输出出现的最频繁的次数。


在RMQ的数组中存的是出现的最多的次数。


代码:

#include <cstdio>#include <iostream>#include <cstring>#include <cmath>using namespace std;int maxsum[200000][30];int a[200000];int b[200000];void RMQ(int n){    for(int i=0;i<n;i++){        maxsum[i][0]=b[i];    }    for(int j=1;(1<<j)<=n;j++){        for(int i=0;i+(1<<j)-1<n;i++){            maxsum[i][j]=max(maxsum[i][j-1],maxsum[i+(1<<(j-1))][j-1]);        }    }}int erfen(int s,int t){//二分    int tmp=a[t];    int l=s;    int r=t;    int mid;    while(l<r){        mid=((l+r)>>1);        if(a[mid]>=tmp)            r=mid;        else            l=mid+1;    }    return r;}int fax(int x,int y){    int k=(int)(log(y-x+1.0)/log(2.0));    return max(maxsum[x][k],maxsum[y-(1<<k)+1][k]);}int main(){    int n,m;    while(~scanf("%d",&n)&&n){        scanf("%d",&m);        for(int i=0;i<n;i++){            scanf("%d",&a[i]);        }        int s,t,tmp;        for(int i=n-1;i>=0;i--){            if(i==n-1)                tmp=1;            else{                if(a[i]==a[i+1])                    tmp++;//次数                else                    tmp=1;            }            b[i]=tmp;        }        RMQ(n);        while(m--){            scanf("%d%d",&s,&t);            s--;//数组下标从零开始的            t--;            int temp=erfen(s,t);            int ans=t-temp+1;            t=temp-1;            if(s>t)                printf("%d\n",ans);            else                printf("%d\n",max(ans,fax(s,t)));        }    }    return 0;}


0 0
原创粉丝点击