zoukankan      html  css  js  c++  java
  • POJ 3368 Frequent values 【ST表RMQ 维护区间频率最大值】

    传送门:http://poj.org/problem?id=3368

    Frequent values
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 23016   Accepted: 8060

    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 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.

    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

    Source

    题意概括:

    给出一串长度为 N 的非递减序列,和 M 次查询, 每次查询区间 【L,R】的出现频率最高的数的频率。

    解题思路:

    很妙的一种做法啊!

    因为他是非递减数列 ,所以基于把每一个连续的相同的数作为同一块处理。

    那么我们可以把查询区间分成两部分来处理。

    第一部分:边界块,区间 起点 L 所处的块 和 区间 R 所处的块。

         如果两者所处的块相同则说明,该区间在一个块内,区间内的数都相同,那么我们所求的最大频率就是当前区间长度了

         如果两者所处的块不相同,那么说明除了这两个块还有其他的块,那么剩下的那些块就是接下来讨论的第二部分。

    第二部分:很显然剩余的块都是连续的,完整的。那么RMQ维护的区间最大值妥妥的,没毛病(这里的最大值就是预处理的每一块的数出现的频率啦)。

    AC code:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cmath>
     5 #define INF 0x3f3f3f3f
     6 using namespace std;
     7 const int MAXN = 1e5+10;
     8 
     9 int num[MAXN];
    10 int hh[MAXN];
    11 int L[MAXN], R[MAXN];
    12 int b[MAXN];
    13 int dpmax[MAXN][20];
    14 int mm[MAXN];
    15 
    16 void init_RMQ(int N, int a[])
    17 {
    18     mm[0] = -1;
    19     for(int i = 1; i <= N; i++){
    20         mm[i] = ((i&(i-1)) == 0)?mm[i-1]+1:mm[i-1];
    21         dpmax[i][0] = b[i];
    22     }
    23     for(int ilen = 1; ilen <= mm[N]; ilen++){
    24         for(int i = 1; i+(1<<ilen)-1 <= N; i++)
    25             dpmax[i][ilen] = max(dpmax[i][ilen-1], dpmax[i+(1<<(ilen-1))][ilen-1]);
    26     }
    27 }
    28 
    29 int get_RMQ(int LL, int RR)
    30 {
    31     int k = mm[RR-LL+1];
    32     return max(dpmax[LL][k], dpmax[RR-(1<<k)+1][k]);
    33 }
    34 
    35 int main()
    36 {
    37     int N, M;
    38     while(~scanf("%d", &N) && N){
    39         scanf("%d", &M);
    40         for(int i = 1; i <= N; i++){
    41             scanf("%d", &num[i]);
    42         }
    43 
    44         int k = 1, ll = 1;
    45         memset(b, 0 ,sizeof(b));
    46 
    47         for(int i = 1; i <= N; i++){
    48             if(i > 1 && num[i] != num[i-1]){
    49                 for(int j = ll; j < i; j++){
    50                     L[j] = ll;
    51                     R[j] = i-1;
    52                 }
    53                 b[k] = i-ll;
    54                 ll = i;
    55                 k++;
    56             }
    57             hh[i] = k;
    58         }
    59 
    60         for(int j = ll; j <= N; j++){
    61             L[j] = ll;
    62             R[j] = N;
    63         }
    64         b[k] = N-ll+1;
    65         init_RMQ(k, b);
    66 
    67         int U, V;
    68         while(M--){
    69             scanf("%d%d", &U, &V);
    70             int st = hh[U], ed = hh[V];
    71             if(st == ed){
    72                 printf("%d
    ", V-U+1);
    73                 continue;
    74             }
    75             int ans = max(R[U]-U+1, V-L[V]+1);
    76             st++, ed--;
    77             if(st <= ed) ans = max(ans, get_RMQ(st, ed));
    78             printf("%d
    ", ans);
    79         }
    80     }
    81     return 0;
    82 }
    View Code
  • 相关阅读:
    Solution -「ARC 101D」「AT4353」Robots and Exits
    Solution -「多校联训」轮回
    Solution -「多校联训」种蘑菇
    Solution -「多校联训」染色
    luoguP4389 完全背包计数
    Js 之notification浏览器桌面通知
    Linux 之shell脚本调用另一个shell脚本
    Linux 之开机自启动脚本
    Js 之简单ajax封装
    PHP 之phpsocket.io客户端主动推送给服务器
  • 原文地址:https://www.cnblogs.com/ymzjj/p/10035352.html
Copyright © 2011-2022 走看看