Frequent values UVA - 11235(RMQ)

Frequent values UVA - 11235

题意:

给出一个非降序排列的数组, a 1 , a 2 , . . . , a n ,对于一系列询问 [ l , r ] 回答 a i , a i + 1 , . . . , a j 中出现次数最多的值所出现的的次数

分析:

因为是非降序的数组,因此相同的数字都在一起,因此可以分段,用cnt[i]记录i段数字出现次数,num[p],l[p],r[p],分别表示位置i所在段的编号和左右端点的位置,每次查询[L,R]的结果可以分为以下三个部分的最大值:

从L到L所在段的结束处的元素个数即(r[L]-L+1),从R所在段开始处到R处的元素个数(即R-l[R]+1),中间第num[L]+1段到第num[R]-1段的最大值

code:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 1e5+10;
int cnt[maxn],l[maxn],r[maxn],num[maxn];
int a[maxn];
int dp[maxn][30];
void RMQ_Init(int t){
    int n = t;
    for(int i = 0; i < n; i++) dp[i][0] = cnt[i];
    for(int j = 1; (1 << j) <= n; j++){
        for(int i = 0; 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 = 0;
    while((1 << (k + 1)) <= R - L + 1) k++;
    return max(dp[L][k],dp[R-(1<<k)+1][k]);
}
int main(){
    int n,q;
    while(~scanf("%d",&n) && n){
        scanf("%d",&q);
        for(int i = 0; i < n; i++){
            scanf("%d",&a[i]);
        }
        memset(cnt,0,sizeof(cnt));
        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));
        int t = 0,tmp = 1;//t记录段号,tmp记录每段的个数
        for(int i = 1; i < n - 1; i++){
            if(a[i] != a[i-1]){
                cnt[t] = tmp;
                r[t] = i - 1;
                t++;
                num[i] = t;
                l[t] = i;
                tmp = 1;
            }
            else{
                tmp++;
                num[i] = t;
            }
        }
        r[t] = n - 1;
        cnt[t] = tmp;
        num[n-1] = t;
        RMQ_Init(t);
        while(q--){
            int x,y;
            scanf("%d%d",&x,&y);
            x--,y--;
            int L = num[x],R = num[y];
            if(L == R){
                printf("%d\n",y-x+1);
                continue;
            }
            int Max = 0;
            Max = max(r[L] - x + 1,y - l[R] + 1);
            if(R - 1 >= L + 1)
                Max = max(Max,RMQ(L+1,R-1));
            printf("%d\n",Max);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/codeswarrior/article/details/82632264