zoukankan      html  css  js  c++  java
  • UVA 11235 Frequent values RMQ

                                          Frequent values

    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 integers a1, . . . , 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 q lines 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.
    Note: A naive algorithm may not run in time!
    Sample Input
    10 3
    -1 -1 1 1 1 1 3 10 10 10
    2 3
    1 10
    5 10
    0
    Sample Output
    1
    4
    3

    题意:

      给你n个数,q次询问

      每次询问是l,r之间重复最多的数的次数

    题解:

      由于这n个数是升序的,我们将其细分问每个位置上的相同数向左向右延生至最左的位置和最右位置,

      处理了这个,利用RMQ求解,判断最大了

      max(RMQ(righti+1,reftj−1),max(righti−i+1,j−leftj+1))

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <map>
    using namespace std ;
    typedef long long ll;
    const int  N = 100000 + 10;
    int a[N],x,q,n,dp[N][20],y,l[N],r[N],h[N];;
    void RMQ() {
        for(int i = 1; i <= n; i++) dp[i][0] = r[h[i]] - l[h[i]] + 1;
        for(int i = 1; (1<<i) <= n; i++) {
            for(int j = 1; (j + (1<<i) - 1) <= n; j++) {
                dp[j][i] = max(dp[j][i-1],dp[j + (1<<(i-1))][i-1]);
            }
        }
    }
    int query(int l,int r) {
        if(l == r) return 1;
        else if(l > r) return 0;
        int k = (int) ((log((double)(r - l + 1))) / log(2.0));
        return max(dp[l][k] , dp[r - (1<<k) + 1][k]);
    }
    map<int,int> mp;
    int main() {
        while(scanf("%d%d",&n, &q) == 2 && n) {
            mp.clear();int cnt = 0;
            memset(h,0,sizeof(h));memset(dp,0,sizeof(dp));
            for(int i = 1; i <= n; i++) {
                scanf("%d",&x);
                if(mp[x]) h[i] = cnt, r[cnt] = i, mp[x]++;
                else h[i] = ++ cnt, l[cnt] = i, r[cnt] = i,mp[x] = 1;
            }
            RMQ();
            for(int i = 1; i <= q; i++) {
                scanf("%d%d",&x,&y);
                if(h[x] == h[y]) printf("%d
    ", y - x + 1);
                else
                printf("%d
    ",max(query(r[h[x]] + 1, l[h[y]] - 1), max(r[h[x]] - x + 1, y - l[h[y]] + 1)));
            }
        }
        return 0;
    }
  • 相关阅读:
    准备 FRM 考试——方法、工具与教训
    930. 和相同的二元子数组 前缀和
    1906. 查询差绝对值的最小值 前缀和
    剑指 Offer 37. 序列化二叉树 二叉树 字符串
    815. 公交路线 BFS
    518. 零钱兑换 II dp 完全背包
    1049. 最后一块石头的重量 II dp
    5779. 装包裹的最小浪费空间 二分
    5778. 使二进制字符串字符交替的最少反转次数 字符串 滑动窗口
    474. 一和零 dp
  • 原文地址:https://www.cnblogs.com/zxhl/p/5164694.html
Copyright © 2011-2022 走看看