您的位置:首页 > 产品设计 > UI/UE

UVa 11235 FrequentValues(RMQ)

2015-07-26 14:25 393 查看

题意:

给一个非降序排列的整数数组a,你的任务是对于一系列询问(i, j),回答ai,ai+1…aj中次数出现最多的值所出现的次数。

解析:

由于数列是非降序的,所以所有相等的数都会聚集在一起。这样我们就可以把整个数组进行编码。如-1,1,1,2,2,2,4就可以编码成(-1,1),(1,2),(2,3),(4,1)表示(a,b)数组中的a连续出现了b次。

用num[i]表示原数组下表是i的数在编码后的第num[i]段。left[i],right[i]表示第i段的左边界和右边界,用coun[i]表示第i段有conu[i]个相同的数。这样的话每次查询(L, R)就只要计算(right[L]-L+1),(R-left[R]+1)和RMQ(num[L]+1, num[R]-1)这三个值的最大值就可以了。

其中,RMQ是对coun数组进行取件查询的结果。

注意:

如果L和R在同一个区间内的话,那么结果就是(R-L+1)

mymy codecode

[code]#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1000010;
int A
, id
, left
, right
;
int cnt
, tot;

struct Interval {
    int ll, rr;
};

map<int, Interval> mp;

int dp[N*2][20];

void rmq_init(int n) {
    for(int i = 1; i <= n; i++)
        dp[i][0] = cnt[i];
    for(int k = 1; (1 << k) <= n; k++) {
        for(int i = 1; i + (1 << k) - 1 <= n; i++) {
            dp[i][k] = max(dp[i][k-1], dp[i+(1<<(k-1))][k-1]);
        }
    }
}

int rmq(int L, int R) {
    if(L > R) return -INF;
    int len = R - L + 1, k = 0;
    while(1 << (k+1) <= len) k++;
    return max(dp[L][k], dp[R-(1<<k)+1][k]);
}

int query(int L, int R) {
    if(id[L] == id[R]) return R - L + 1;
    int mid = rmq(id[L]+1, id[R]-1);
    int ll = right[L] - L + 1;
    int rr = R - left[R] + 1;
    return max(mid, max(ll, rr));
}

int main() {
    int n, q;
    while(scanf("%d", &n) != EOF && n) {
        scanf("%d", &q);
        mp.clear();
        A[0] = -INF;
        tot = 0;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &A[i]);
            if(A[i] != A[i-1]) {
                mp[A[i]] = (Interval){i, i};
                id[i] = ++tot, left[i] = i;
                cnt[tot] = 1;
            }else {
                mp[A[i]].rr = i;
                id[i] = tot, left[i] = mp[A[i]].ll;
                cnt[tot]++;
            }
        }
        for(int i = 1; i <= n; i++) right[i] = mp[A[i]].rr;

        rmq_init(tot);
        int ql, qr;
        while(q--) {
            scanf("%d%d", &ql, &qr);
            printf("%d\n", query(ql, qr));
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: