UVA11235 Frequent values (RMQ)

题意:给一个数组,然后问你在区间(L,R)里相同数字出现的最多次数。。

分析:因为是非降序的,所有相同的元素会聚集到一起。这个就可以把整个数组进行编码,变成出现次数为数组的值的数组,然后求区间的最大值即可。

比如-1,1,1,2,2,2,4就可以编码成(-1,1)(1,2)(2,4)(4,1),其中(a,b)表示有b个连续的a

G[i]为第i段的值,cnt[i]为第i段的个数,F[i]为第i段的左端点位置,R[i]为第i段右端点的位置,pos[i]为第i个数所在的段

// File Name: 11235.cpp
// Author: zlbing
// Created Time: 2013/3/9 21:32:31

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,n) for(int i=0;i<n;i++)
#define REP1(i,n) for(int i=1;i<n+1;i++)
#define MAXN 100050
int d[MAXN][20];
int G[MAXN];
int cnt[MAXN];
int F[MAXN],R[MAXN];
int pos[MAXN*2];
int len;

void init_RMQ(int n)
{
    for(int i=1;i<=n;i++)d[i][0]=cnt[i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            d[i][j]=max(d[i][j-1],d[i+(1<<j-1)][j-1]);
}
int max_RMQ(int a,int b){
    int k=0;
    while((1<<k)<=b-a+1)k++;
    return max(d[a][k-1],d[b-(1<<(k-1))+1][k-1]);
}
int main(){
    int n,q;
    while(~scanf("%d",&n)){
        if(!n)break;
        scanf("%d",&q);
        CL(cnt,0);
        len=0;
        int a,b;
        REP1(i,n){
            scanf("%d",&a);
            if(len==0){
                G[++len]=a;
                cnt[len]++;
                F[len]=1;
                pos[i]=len;
            }else{
                if(a==G[len]){
                    cnt[len]++;
                    pos[i]=len;
                }
                else {
                    R[len]=i-1;
                    G[++len]=a;
                    cnt[len]++;
                    F[len]=i;
                    pos[i]=len;
                }
            }
        }
        R[len]=n;
        init_RMQ(len);
        REP(i,q){
            scanf("%d%d",&a,&b);
            int aa=pos[a];
            int bb=pos[b];
            if(aa==bb)printf("%d\n",b-a+1);
            else{
                int ans=R[aa]-a+1;
                ans=max(b-F[bb]+1,ans);
                ans=max(ans,max_RMQ(aa+1,bb-1));
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/arbitrary/p/2952890.html