poj 3368(RMQ应用)

来源:互联网 发布:驱动下载软件 编辑:程序博客网 时间:2024/05/17 02:23
Frequent values
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 8555 Accepted: 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 102 31 105 100

Sample Output

143

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[n]=a[n],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;}