UVA11235 - Frequent values(BMQ)

题目链接

题目大意:可以一串不递减的序列,然后给你一个范围L,R,要求你返回L,R出现最多次的那个值的出现次数。

解题思路:将这个序列重新编码一下,把相同的数字标记成一段,然后用num记录是哪一段,用cnt记录一下出现了多少个相同的。然后查询的时候因为可能出现从一段中的某个部分开始的情况,所以要先将头和尾处理一下,标记每一段的最左端和最右端位置。中间完整的部分用BMQ。

#include <cstdio>
#include <cstring>
#include <vector>
#include <map>

using namespace std;

const int N = 1e5 + 5;
const int M = 20;

int left[N], right[N];
int A[N];

struct Num {

    int value, count;
    Num (const int value = 0, const int count = 0): value(value) , count(count) {}
};

vector<Num> v;
map<int, int> num;

int d[N][M];
int n;

void RMQ_init () {

    int l = v.size();
    for (int i = 0; i < l; i++)
        d[i][0] = v[i].count;
    for (int j = 1; (1<<j) <= l; j++)
        for (int i = 0; i + (1<<j) - 1 < l; i++)
            d[i][j] = max (d[i][j - 1], d[i + (1<<(j - 1))][j - 1]);
}

int RMQ (int l, int r) {

    int k = 0;
    while ((1<<(1 + k)) <= (r - l + 1)) k++;
    return max (d[l][k], d[r - (1<<k) + 1][k]);
}

int main () {

    int q;
    while (scanf ("%d", &n) && n) {

        scanf ("%d", &q);

        v.clear();
        num.clear();

        for (int i = 0; i < n; i++) {
            scanf ("%d", &A[i]);
            if (v.size() && v[v.size() - 1].value == A[i])
                v[v.size() - 1].count++;
            else {

                num[A[i]] = v.size();
                v.push_back(Num(A[i], 1));
                left[num[A[i]]] = i;
            }
        }

        for (int i = 0; i < v.size(); i++)
            right[num[v[i].value]] = left[num[v[i].value]] + v[i].count - 1;

        RMQ_init();

        int l, r;
        int ans;
        while (q--) {

            scanf ("%d%d", &l, &r);
            l--;
            r--;
            if (A[l] != A[r]) {
                ans = max (right[num[A[l]]] - l + 1, r - left[num[A[r]]] + 1);
                if (num[A[l]] + 1 <= num[A[r]] - 1)
                    ans = max (ans, RMQ(num[A[l]] + 1, num[A[r]] - 1));
            } else
                ans = r - l + 1;
            printf ("%d\n", ans);
        }
    }
    return 0;
}
时间: 2024-11-02 13:01:00

UVA11235 - Frequent values(BMQ)的相关文章

uva11235(Frequent values)(HDU1806)

题目地址:Frequent values 题目大意.解题思路:  见白皮书p198. 代码: 1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <algorithm> 5 #include <vector> 6 using namespace std; 7 const int M=100100; 8 int a[M]; 9 int val[M],cn

[uva11235]Frequent values(RMQ,ST,离散化)

题目链接:https://vjudge.net/problem/UVA-11235 题意:给一串不递减数字,q次询问,每次查询[l,r]内出现次数最多的数字出现的次数. 查询分两部分:一部分是[l,r]为同一个数的区间,另一部分则是在上下界处截取一部分的情况. 首先离散化,后用l[],r[],v[]分别记录每一段相同数字的左右区间和出现次数.v可以直接由r-l+1更新得到. 第一部分更新ret后,接下来的rmq分三部分: 第一部分查询左边界截取一部分的数字的当前长度,第二部分查询右边界的,第三部

UVA-11235 Frequent values (RMQ)

题目大意:在一个长度为n的不降序列中,有m次询问,每次询问(i,j)表示在区间(i,j)中找出出现次数最多的元素的出现次数. 题目分析:因为序列有序,可以将序列分段,并且记录每段的元素个数.每一个元素所属的段num(i).每一个元素所属段的左端点l(i)及右端点r(i).那么对于每次询问: ans(i,j)=max(max(r(i)-i+1,j-l(j)+1),rmq(num(i)+1,num(j)-1)). ans(i,j)=r-j+1 (如果i与j属于同一段) 代码如下: # include

poj 3368 Frequent values(线段树解法)

题目链接:http://poj.org/problem?id=3368 题目大意:给你一段不下降的序列,求给定区间里出现次数最多的那个数字的次数. 思路:首先看到这题时,第一感觉线段树,但是仔细一看问题来啦,用线段数我怎么才能计算出某段区间里出现的那个数,因为出现最多的那个数可能不是在他它的左儿子上也不是在它的右儿子上,可能在当他们合并成一个区间时就出现啦,但是这儿我们需要注意的就是,题目给的是一段不下降的序列,那么突破口就出来啦,因为如果出现相同的数字,那么它们一定是连续的.所以我们只需要在普

UVA 11235 Frequent values(RMQ)

Frequent values TimeLimit:3000Ms 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 f

【POJ 3368】 Frequent values(RMQ)

[POJ 3368] Frequent values(RMQ) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15813   Accepted: 5749 Description You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given seve

poj 3368 Frequent values(线段树)

Frequent values Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13516   Accepted: 4971 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 cons

【暑假】[实用数据结构]UVa11235 Frequent values

UVa 11235 Frequent values Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11241   Accepted: 4110 Description You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several qu

POJ 3368 Frequent values(RMQ)

Frequent values Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15134   Accepted: 5519 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 cons